O que depois do exec () no comando ls. O processo pai está imprimindo a saída para o console ou o filho?

3

Eu tenho uma dúvida simples sobre a execução do comando ls . Conforme meu entendimento da pesquisa que fiz na internet, entendi os pontos abaixo.

  1. Quando digitamos o comando ls, o shell interpreta esse comando.

  2. Em seguida, o processo de shell se bifurca e cria o processo filho & o pai (shell) executa a chamada do sistema wait() , colocando-se efetivamente no modo de espera até que a criança saia.

  3. O processo filho herda todos os descritores de arquivos abertos e o ambiente.

  4. Em seguida, o processo filho executa um exec() do programa ls. Isso lê o programa ls do seu arquivo de programa no disco para o processo [filho] existente.

  5. Quando o programa ls é executado até a conclusão, ele chama exit() e envia um sinal ao pai indicando que o filho foi encerrado.

Minha dúvida começa daqui em diante, assim que ls termina suas tarefas, ele envia o resultado de volta ao processo pai ou ele próprio exibe a saída para a tela ?. Se ele envia o o / p de volta para o pai, então ele está usando pipe() implicitamente?

    
por Subi Suresh 14.03.2013 / 19:28

3 respostas

2

Normalmente, o processo pai aguarda até que o processo filho termine chamando waitpid . O processo pai obtém o PID do processo de fork .

Isso significa que a criança nunca sinaliza o processo pai de qualquer maneira que ele tenha saído ou o que aconteceu. Isso é feito pelo sistema e não pelo processo filho.

Se você está falando sobre a saída do programa, o pai normalmente nunca recebe a saída do processo filho, a menos que forneça fds. Isso também significa que o processo filho imprime a saída e não o processo pai. O processo pai apenas recebe informações sobre o estado do processo (para obter mais informações, consulte as macros no waitpid manpage)

    
por 14.03.2013 / 19:39
2

ls produzirá o que deve ser produzido em sua saída padrão . Para fazer isso, ele chama a chamada do sistema write , algo como:

 write(1, "file1  file2...\n", 16)

(ou, mais provavelmente, chama libc funções como printf ou fwrite que eventualmente fazem a chamada do sistema write() )

Ele assume que o descritor de arquivo 1 (stdout por convenção) já estava aberto e aponta para algo. Na verdade, ls verifica se o descritor de arquivo 1 aponta para um terminal ou outra coisa. Se não apontar para um terminal, ele será exibido:

 write(1, "file1\nfile2...\n", 15)

Ou seja, ele grava um arquivo por linha quando a saída não vai para um terminal.

Quando você escreve:

 ls file1 file2
O descritor de arquivo 1 de

ls apontará para o mesmo recurso que o fd 1 do shell (assim, por exemplo, se foi um shell interativo iniciado por xterm , que apontará para o dispositivo pseudo-terminal controlado por xterm). O shell não faz nada de especial, ele é herdado em fork e, como o sinalizador O_CLOEXEC normalmente não está definido no descritor de arquivo, ele é preservado em execve .

Se você escrever:

var=$(ls file1 file2)

O shell cria um pipe e atribui o fd 1 do processo filho à extremidade de gravação desse pipe e lê o outro extremo do pipe para preencher a variável var .

Não é feito magicamente após a saída, é apenas feito como parte do trabalho do processo. É independente de qualquer outra atividade do shell. ls é apenas outro processo com seu fd 1 conectado a algum recurso como o terminal, enquanto o shell é outro processo ocupado fazendo um waitpid() .

O que você pode achar é que quando o stdout não é um terminal, ls armazena sua saída e só chamaria write() quando dados suficientes (o suficiente sendo vários kilobytes) foram acumulados ou estão fechando sua saída ou estão saindo . Assim, a esse respeito, você encontrará o write concluído ao sair, mas apenas como parte do flushing dos buffers que estão sendo feitos por essas bibliotecas de E / S.

    
por 14.03.2013 / 21:27
1

Se exec(3) for bem sucedido, o programa que o chamou não é mais. É substituído pelo programa exec ed. O novo programa em execução herda o ambiente, em particular os arquivos abertos, do original.

    
por 14.03.2013 / 19:31