Estou executando um executável simples chamado hello
bash. Ele consulta um usuário para obter informações e imprime uma resposta. Eu corro assim ./hello
.
Tanto a solicitação quanto a digitação da resposta pelo usuário ocorrem no shell atual, mas pensei que deveria ser executado em um shell diferente. Presumi isso porque você pode usar source para executar o exe no shell atual.
Alguém pode explicar como isso funciona para mim?
Ao tentar pesquisar isso, muitas vezes me deparo com os termos "ambiente shell" e "contexto shell". Eles são a mesma coisa?
Responder1
Você pode dizer "ambiente 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 shell" é um termo não comumente usado, mas presumo que seria equivalente ao "contexto do processo". No caso de um script shell, isso incluiria o ambiente shell, bem como as variáveis atuais do shell, descritores de arquivo (entrada padrão, saída padrão e erro padrão, e quaisquer outros abertos explicitamente), manipuladores de sinal (instalados com trap
) etc. fosse um programa C, o contexto do processo seria herdado por meio de uma chamada para fork()
, mas não por meio de uma chamada subsequente exec()
(apenas o ambiente sobreviveria a uma chamada para exec()
).
Quando você executa seu hello
programa, que presumo ser um script de shell, a entrada e a saída acontecem no contexto do shell que está executando o hello
script. 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()
and exec()
para iniciar o shell que eventualmente executará o hello
script.
O fato de o hello
script estar solicitando o mesmoterminalcomo onde você iniciou o script significa apenas que o shell que executa o script é o processo atual em primeiro plano. O shell pai está aguardando a conclusão. Quando terminar, o shell pai será mais uma vez o processo em 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 pode modificar o contexto e o ambiente do shell interativo. Por exemplo, ele pode alterar o diretório de trabalho atual (alterar o ambiente) ou instalar um manipulador de sinal (alterar o contexto), e essas alterações ainda estarão "ativas" quando o script terminar a execução.
Se o hello
programa for um binário compilado, ele herdará o ambiente do shell de chamada, mas não compartilhará seu contexto (descritores de arquivo, etc.). Na verdade, ele não está sendo executado em um subshell, pois não é um script de shell. O shell pai ficará em segundo plano, aguardando a conclusão do programa, assim como faria com um script de shell. Do ponto de vista do shell pai, não há diferença entre iniciar um binário compilado ou um script de shell.
Um binário compilado não pode ser iniciado com source
ou .
(ponto), pois o shell não sabe como interpretar um arquivo binário.
Há um pouco de agitação nesta resposta, mas acredito que esteja basicamente correta. Por favor, deixe um comentário (ou edite) se algo precisar ser corrigido ou adicionado.