O arquivo executável “em execução” está no shell ou no sub shell atual?

1

Estou executando um executável simples chamado hello no bash. Consulta um usuário para entrada e imprime uma resposta. Eu corro assim ./hello .

Tanto a solicitação quanto o usuário digitando sua resposta ocorrem no shell atual, mas achei que ela deveria ser executada em um shell diferente. Eu assumi isso porque você pode usar o código-fonte para executar o exe no shell atual.

Alguém pode explicar como isso funciona para mim?

Ao tentar pesquisar isso, eu sempre me deparo com os termos "ambiente de shell" e "contexto de shell". Eles são a mesma coisa?

    
por Þór Óðinsson 26.05.2017 / 20:26

1 resposta

2

Você pode dizer "ambiente de shell" sobre o ambiente do shell atual, que inclui as variáveis de ambiente atuais. O ambiente é herdado por qualquer subprocesso iniciado (subshell ou outro).

O "contexto da shell" é um termo que não é comumente usado, mas estou assumindo que seria equivalente ao "contexto do processo". No caso de um shell script, isso incluiria o ambiente do shell, assim como as variáveis atuais do shell, descritores de arquivo (entrada padrão, saída padrão e erro padrão, e quaisquer outros explicitamente abertos), manipuladores de sinais (instalados com trap ) etc. Se fosse um programa em C, o contexto do processo seria herdado em uma chamada para fork() , mas não em uma chamada exec() subsequente (somente o ambiente sobreviveria a uma chamada para exec() ).

Quando você executa o programa hello , que estou supondo ser um script de shell, a entrada e a saída ocorrem no contexto do shell que está executando o script hello . Este é "o shell atual". O shell que você digitou ./hello é seu shell pai e hello herda seu ambiente.

Internamente, o shell pai faz uma chamada fork() e exec() para iniciar o shell que eventualmente executará o script hello .

O fato de que o script hello está solicitando no mesmo terminal de onde você iniciou o script significa apenas que o shell que está executando o script é o atual processo de primeiro plano. O shell pai está aguardando que ele seja concluído. Quando terminar, o shell pai será novamente o processo de primeiro plano no terminal.

Quando você inicia o script com source ./hello ou . ./hello , o script é executado no mesmo contexto do shell em que você digitou o comando. Isso significa que ele pode modificar o contexto e o ambiente do shell interativo. Por exemplo, ele pode alterar o diretório de trabalho atual (altera o ambiente) ou instalar um manipulador de sinal (altera o contexto), e essas alterações ainda estariam "ativas" quando o script terminar a execução.

Se o programa hello for um binário compilado, ele herdará o ambiente do shell de chamada, mas não compartilhará seu contexto (descritores de arquivo, etc.). Não está realmente rodando em um subshell já que não é um shell script. O shell pai se moverá para o segundo plano, aguardando a conclusão do programa, assim como faria para um script de shell. Do ponto de vista do shell pai, não há diferença entre iniciar um binário compilado ou um shell script.

Um binário compilado pode não ser iniciado com source ou . (ponto), pois o shell não sabe como interpretar um arquivo binário.

Há um pouco de mão acenando nesta resposta, mas acredito que é basicamente correto. Por favor, deixe um comentário (ou edite) se algo precisar ser corrigido ou adicionado.

    
por 26.05.2017 / 20:33

Tags