Caso de uso / exemplo prático para exec builtin do Bash

12

Considere isso a partir da documentação do exec integrado do Bash:

exec replaces the shell without creating a new process

Por favor, forneça um caso de uso / exemplo prático. Eu não entendo como isso faz sentido.

Pesquisei e pesquisei sobre o redirecionamento de E / S . Você pode explicar melhor?

    
por Ivanov 19.03.2016 / 20:19

4 respostas

18

exec é frequentemente usado em scripts de shell que atuam principalmente como wrappers para iniciar outros binários. Por exemplo:

#!/bin/sh

if stuff;
    EXTRA_OPTIONS="-x -y -z"
else
    EXTRA_OPTIONS="-a foo"
fi

exec /usr/local/bin/the.real.binary $EXTRA_OPTIONS "$@"

para que, após o término da execução do wrapper, o binário "real" assuma o controle e não haja mais nenhum rastreio do script de wrapper que ocupou temporariamente o mesmo slot na tabela de processos. O binário "real" é um filho direto de qualquer coisa que tenha sido lançado em vez de um neto.

Você mencionou também o redirecionamento de E / S em sua pergunta. Esse é um caso de uso bastante diferente de exec e não tem nada a ver com a substituição do shell por outro processo. Quando exec não tem argumentos, assim:

exec 3>>/tmp/logfile

então os redirecionamentos de E / S na linha de comando entram em vigor no processo de shell atual, mas o processo de shell atual continua em execução e passa para o próximo comando no script.

    
por 19.03.2016 / 20:42
5

Eu usei um shell exec builtin para obter um ID de 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. Uma vez que um processo tenha seu próprio PID, ele pode gravar isso em um arquivo PID (procure em /var/run/ por nomes de arquivo com um sufixo '.pid') para permitir que os programas de gerenciamento conheçam o PID do processo em execução e evitar uma segunda instância do mesmo servidor seja executada. Funciona assim:

exec java -cp=YourServer.jar StartClass -p $$

O código no método main() da classe StartClass manipula a análise de argumentos e pode encontrar seu próprio ID de processo.

    
por 19.03.2016 / 20:46
2

Para se divertir, execute o programa a seguir (traduzido para o idioma de sua escolha de escolha) em segundo plano em um sistema com contabilidade e limites do processo do usuário.

while(true) fork();

Agora que cada slot da tabela de processos que você tem permissão para usar está repleto de cópias desse programa em execução, como você pretende eliminá-lo? Lançar kill (1) requer outro slot de processo, o qual você não pode ter. Com certeza seria útil que o shell se substituísse pelo comando kill ...

exec /bin/kill -9 -1

(Assume que seu sistema matou (1) em / bin / kill. "exec 'que mata' -9 -1" é potencialmente mais seguro.) Isso envia o SIGKILL para cada processo que você puder.

(Nota: não saia do seu shell de inicialização a menos que os limites do processo sempre permitam um novo login em um slot de processo para seu shell. Isso pode ser um pouco mais difícil de limpar se você fizer isso. Eu certamente não fiz isso no início dos anos 90. Não.)

    
por 19.03.2016 / 22:51
1
  • Isso é semelhante ao exemplo de Bruce de precisar saber o PID de um processo:

    ( cmdpid=$BASHPID; (sleep 300; kill "$cmdpid") & exec long-running-command )

    em que você

    1. Iniciar um subshell (o exterior ( e ) ),
    2. Descubra o PID do subshell. ( $$ lhe dará o PID do shell principal).
    3. Desanexe um sub-subshell que mata seu processo após um tempo limite e
    4. Execute um comando no processo do subshell que você criou na etapa1.

    Isso executará long-running-command , mas apenas por um período de tempo limitado e pré-determinado.

  • Isso é um pouco frívolo, mas se você decidir que quer ser root (ou algum outro usuário) para o resto da sua sessão de login, você poderia 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, há um problema em interromper a conexão e iniciar uma nova conexão. Por exemplo, suponha que o sistema remoto tenha um firewall que segue um cronograma. Você foi autorizado a se conectar quando você fez, e conexões estabelecidas não são fechadas, mas no momento atual, 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 de senha aparecer, gire a estação de trabalho para ele. Agora não há processo com seu UID (a menos que você tenha executado algo no fundo), então Bob não poderá mexer em seus arquivos. Ele terá efetivamente assumido sua conexão (com o seu consentimento e cooperação).

    Notas:

    • É claro que isso não funcionará se você não tiver permissão para executar su .
    • Ele será registrado, então você pode precisar explicar seus motivos para alguém. Desde que você está contornando a política (a programação do firewall), você pode ter problemas.
    • Não garanto que seja 100% seguro. Por exemplo, who provavelmente ainda mostrará seu nome. É concebível que algum programa (mal escrito) vai usar isso para pensar que Bob é você, e dar-lhe acesso aos seus recursos.
    • Se o sistema fizer auditoria, As ações de Bob podem ser auditadas em seu nome.
por 20.03.2016 / 07:04