Considere isso na documentação do exec incorporado do Bash:
exec substitui o shell sem criar um novo processo
Forneça um caso de uso / exemplo prático. Não entendo como isso faz sentido.
Eu pesquisei e encontrei cerca de I / O redirecionamento . Você pode explicar melhor?
bash
shell-script
exec
shell-builtin
Ivanov
fonte
fonte
Respostas:
exec
é frequentemente usado em scripts de shell que atuam principalmente como wrappers para iniciar outros binários. Por exemplo:para que, após a conclusão da execução do wrapper, o binário "real" assuma o controle e não haja mais nenhum rastreamento do script do wrapper que ocupou temporariamente o mesmo slot na tabela de processos. O binário "real" é um filho direto de tudo o que o lançou, em vez de um neto.
Você também mencionou o redirecionamento de E / S na sua pergunta. Esse é um caso de uso bem diferente
exec
e não tem nada a ver com a substituição do shell por outro processo. Quandoexec
não tem argumentos, assim:os redirecionamentos de E / S na linha de comando entram em vigor no processo atual do shell, mas o processo atual do shell continua em execução e passa para o próximo comando no script.
fonte
exec
diz ao shell para não executar a ação (executar um comando ou executar um redirecionamento) em um processo filho, mas no mesmo processo.Eu usei um shell
exec
embutido para obter um ID do processo (PID) para um programa Java. Pode haver uma maneira de obter o PID de dentro do Java agora, mas há vários anos, não havia. Depois que um processo possui seu próprio PID, ele pode gravá-lo em um arquivo PID (procure/var/run/
nomes de arquivos com o sufixo '.pid') para permitir que os programas de gerenciamento saibam o PID do processo em execução e para impedir uma segunda instância do mesmo servidor em execução. Funciona mais ou menos assim:O código no
main()
método da classeStartClass
manipula a análise de argumentos e pode encontrar seu próprio ID do processo.fonte
Por diversão, execute o seguinte programa (traduzido para o idioma de sua escolha) em segundo plano em um sistema com contabilidade e limites de processo do usuário.
Agora que todos os slots na tabela de processos que você tem permissão para usar estão cheios de cópias desse programa em execução, como pretende eliminá-lo? O lançamento do kill (1) requer outro slot de processo, que você não pode ter. Certamente seria útil fazer com que o shell se substituísse pelo comando kill ...
(Supõe que seu sistema tenha kill (1) em / bin / kill. "Exec`, que mata` -9 -1 "é potencialmente mais seguro.) Isso envia o SIGKILL para todos os processos que você puder.
(Nota: Não efetue logout no shell de inicialização, a menos que os limites do processo sempre permitam um novo login em um slot de processo para o shell. Isso pode ser um pouco mais difícil de limpar se você o fizer. Certamente não fiz isso no início dos anos 90. Não.)
fonte
exec
comando que seria útil nessa situação. (2) Essa resposta é um pouco arcaica; okill
comando é um comando embutido no bash há muitos anos, em grande parte por causa dessa preocupação.exec
- e o fato dekill
ser um builtin não tem realmente nada a ver com oexec
builtin.`which kill`
) também não funcionará. (2) BTW, o$(…)
formulário é recomendado sobre o`…`
formulário. (3) Mas não há nada perigoso em adivinhar o diretório. Se você digitar acidentalmenteexec /binn/kill
, você receberá uma mensagem de erro e seu shell não desaparecerá. (4) Mas você nem precisa se preocupar com qual diretório okill
.exec
Usa$PATH
, assim como os comandos normais, assimexec kill …
funciona (supondo que você tenha/bin
no seu caminho de pesquisa).Isso é semelhante ao exemplo de Bruce de precisar conhecer o PID de um processo:
em que você
(
e)
),$$
fornecerá o PID do shell principal.)Isso será executado
long-running-command
, mas apenas por um período de tempo limitado predeterminado.Isso é um pouco frívolo, mas, se você decidir ser root (ou algum outro usuário) pelo resto da sua sessão de login, poderá
exec su
.Na verdade, posso imaginar um cenário em que isso seria realmente útil. Suponha que você esteja conectado a um sistema remoto e, por algum motivo, haja um problema ao interromper a conexão e iniciar uma nova conexão. Por exemplo, suponha que o sistema remoto tenha um firewall que siga um cronograma. Você teve permissão para se conectar quando o fez e as conexões estabelecidas não são fechadas, mas, no momento, novas conexões não estão sendo aceitas.
Você fez o que queria e está pronto para sair. Seu amigo Bob está na sala com você e ele quer fazer algum trabalho no sistema remoto - mas ele não poderá se conectar. Então, você digita
exec su - bob
e, quando o prompt da senha aparecer, entregue a estação de trabalho para ele. Agora não há nenhum processo com o seu UID (a menos que você tenha executado algo em segundo plano), então Bob não poderá mexer nos seus arquivos. Ele efetivamente assumiu sua conexão (com seu consentimento e cooperação).Notas:
su
.who
provavelmente ainda mostrará seu nome. É concebível que algum programa (mal escrito) use isso para pensar que Bob é você e dar a ele acesso aos seus recursos.fonte
(a;b)
já é o mesmo(a;exec b)
que os shells otimizam o garfo para o último comando em um subshell. As únicas exceções parecem serbash
emksh
. Usarexec
ajuda para garantir isso.