Como o bash realmente altera stdin / stdout / stderr ao usar redirecionamento / piping

3

Infelizmente, não tive sorte em descobrir isso, já que tudo que encontro é apenas a sintaxe do redirecionamento ou informações superficiais sobre como o redirecionamento funciona.

O que eu quero saber é como o bash realmente altera stdin / stdout / stderr quando você usa pipes ou redirecionamento. Se, por exemplo, você executa:

ls -la > diroutput.log

Como isso muda stdout de ls para diroutput.log ?

Suponho que funcione assim:

  • Bash executa fork(2) para criar uma cópia de si mesmo
  • O processo de bash bifurcado define stdout to diroutput.log usando algo como freopen(3)
  • O processo bash bifurcado executa execve(2) ou uma função exec semelhante para se substituir por ls , que agora usa a stdout setup por bash

Mas esse é apenas meu palpite.

    
por Brandon Wamboldt 05.08.2014 / 01:20

1 resposta

4

Consegui descobrir usando strace -f e escrevendo uma pequena prova de conceito em C.

Parece que o bash apenas manipula os descritores de arquivos no processo filho antes de chamar execve como eu pensava.

Veja como ls -la > diroutput.log funciona (aproximadamente):

  • chamadas do bash fork(2)
  • processo bash bifurcado vê o redirecionamento de saída e abre o arquivo diroutput.log using open(2) .
  • o processo bash bifurcado substitui o descritor de arquivo stdout usando dup2(2) syscall
  • bash chama execve(2) para substituir sua imagem executável por ls , que então herda a configuração stdout

Os syscalls relevantes são assim ( strace output):

6924  open("diroutput.log", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 
6924  dup2(3, 1)                        = 1 
6924  close(3)                          = 0 
6924  execve("/bin/ls", ["ls", "-la"], [/* 77 vars */]) = 0
    
por 05.08.2014 / 01:40

Tags