Como um shell executa um programa?

11

Se eu compilar um programa usando o gcc, e tentar executá-lo a partir do bash shell, qual é a seqüência exata de passos seguidos pelo bash para executá-lo?

Eu sei que fork() , execve() , loader , dynamic linker (e outras coisas) estão envolvidos, mas alguém pode dar uma sequência exata de etapas e alguma referência de leitura adequada?

Editar:

Das respostas, parece que a pergunta poderia implicar muitas possibilidades. Quero me limitar a um caso simples:

(test.c apenas imprime hello world)

$ gcc test.c -o test
$ ./test

Quais serão as etapas do caso acima ( ./test ), especificamente relacionadas ao bash starting program em algum processo filho, carregando, vinculando etc.?

    
por Jake 27.08.2015 / 01:22

3 respostas

5

Bem, a sequência exata pode variar, pois pode haver um alias ou função de shell que primeiro seja expandida / interpretada antes que o programa seja executado e, em seguida, diferenças para um nome de arquivo qualificado ( /usr/libexec/foo ) versus algo que será procuramos por todos os diretórios da variável de ambiente PATH (apenas foo ). Além disso, os detalhes da execução podem complicar, pois foo | bar | zot requer mais trabalho para o shell (alguns fork(2) , dup(2) e, é claro, pipe(2) , entre outras chamadas do sistema), enquanto algo como exec foo é muito menos trabalho como o shell apenas substitui-se com o novo programa (ou seja, não fork ). Também são importantes os grupos de processos (especialmente o grupo de processos em primeiro plano, todos os PIDs que comem SIGINT quando alguém inicia o processamento em Ctrl + C , sessões e se o trabalho é será executado em segundo plano, monitorado ( foo & ) ou em segundo plano, ignorado ( foo & disown ). Os detalhes de redirecionamento de E / S também mudarão as coisas, por exemplo, se a entrada padrão for fechada pelo shell ( foo <&- ), ou se um arquivo é aberto como stdin ( foo < blah ).

strace ou similar será informativo sobre as chamadas de sistema específicas feitas ao longo deste processo, e deve haver páginas de manual para cada uma dessas chamadas. A leitura adequada do nível do sistema seria qualquer número de capítulos da "Programação Avançada no Ambiente UNIX" de Stevens, enquanto um livro de shell (por exemplo, "Do Bash ao Z Shell") abordará o lado do shell em detalhes.

    
por 27.08.2015 / 02:07
1

Supondo um shell de exemplo de livro didático (para clareza de código) que já está em execução (para que o vinculador dinâmico seja feito), os comandos que você mencionou exigirão que o shell faça as seguintes chamadas de sistema:

  • read: obtém o próximo comando neste caso gcc
  • fork: são necessários dois processos, assumimos que o pai tem pid 500 e o filho como ilustração.
  • o pai chamará wait (501), enquanto o filho chamará exec. Neste ponto, o shell não está mais sendo executado no pid 501. O gcc faz muitas chamadas do sistema, incluindo, no mínimo, abrir, fechar, ler, gravar, chmod, fork, exec, wait e exit.
  • quando as chamadas do gcc saem, a espera retorna, a gravação é chamada para exibir o prompt e o processo será repetido.

Comandos mais complicados naturalmente adicionam mais complicações a esta sequência básica. Dois exemplos mais simples de complicações básicas são o redirecionamento io básico, no qual uma seqüência open, close, dup é inserida entre o fork e os processos exec e background onde a espera é ignorada (e outra espera é adicionada ao manipulador sigchld).

    
por 27.08.2015 / 05:27
0

Sugiro ler Seção 8.4.6 Usando fork e execve para executar programas

em link

    
por 24.05.2016 / 10:46