Quais são os usos do comando exec em scripts de shell?

249

Alguém pode explicar quais são os usos do comando exec em scripts de shell com exemplos simples?

user2400564
fonte
31
Os links para linux.about.com não são úteis. Eles não deixam remotamente claro como a execução de um comando ou pipeline de comandos usando 'exec' difere de apenas executá-los normalmente. Daí a pergunta do OP "qual é a utilidade do exec"?
Jonathan Hartley
2
Stack Overflow é um site para perguntas sobre programação e desenvolvimento. Esta questão parece estar fora de tópico, porque não se trata de programação ou desenvolvimento. Consulte Quais tópicos posso perguntar aqui na Central de Ajuda. Talvez o Superusuário ou o Unix e Linux Stack Exchange sejam um lugar melhor para perguntar.
JWW

Respostas:

281

o exec comando interno espelha funções no kernel, com base em uma família delas execve, geralmente chamada de C.

exec substitui o programa atual no processo atual, sem fork um novo processo. Não é algo que você usaria em todos os scripts que escrever, mas é útil ocasionalmente. Aqui estão alguns cenários que eu usei;

  1. Queremos que o usuário execute um programa aplicativo específico sem acesso ao shell. Poderíamos alterar o programa de entrada em / etc / passwd, mas talvez desejemos que a configuração do ambiente seja usada nos arquivos de inicialização. Então, em (digamos) .profile, a última declaração diz algo como:

     exec appln-program

    então agora não há shell para voltar. Mesmo se appln-programtravar, o usuário final não pode acessar um shell, porque ele não está lá - oexec substituiu.

  2. Queremos usar um shell diferente daquele no / etc / passwd. Por mais estúpido que pareça, alguns sites não permitem que os usuários alterem seu shell de entrada. Eu conheço um site onde todos começaram csh, e todos colocaram em seu .login(arquivo de inicialização do csh) uma chamada ksh. Enquanto isso funcionava, ele deixou um cshprocesso disperso em execução, e o logout foi em dois estágios, o que poderia ser confuso. Então, mudamos para o exec kshque acabou de substituir o programa c-shell pelo korn shell, e simplificamos tudo (há outros problemas com isso, como o fato de o arquivoksh não ser um shell de login).

  3. Apenas para salvar processos. Se chamarmosprog1 -> prog2 -> prog3 -> prog4 etc. e nunca voltarmos, faça de cada ligação um executivo. Economiza recursos (não muito, a menos que seja repetido) e simplifica o desligamento.

Você obviamente viu execusado em algum lugar, talvez se você mostrasse o código que está incomodando, poderíamos justificar seu uso.

Edit : Eu percebi que minha resposta acima está incompleta. Existem dois usos de execshells como kshe bash- usados ​​para abrir descritores de arquivos. aqui estão alguns exemplos:

exec 3< thisfile          # open "thisfile" for reading on file descriptor 3
exec 4> thatfile          # open "thatfile" for writing on file descriptor 4
exec 8<> tother           # open "tother" for reading and writing on fd 8
exec 6>> other            # open "other" for appending on file descriptor 6
exec 5<&0                 # copy read file descriptor 0 onto file descriptor 5
exec 7>&4                 # copy write file descriptor 4 onto 7
exec 3<&-                 # close the read file descriptor 3
exec 6>&-                 # close the write file descriptor 6

Observe que o espaçamento é muito importante aqui. Se você colocar um espaço entre o número fd e o símbolo de redirecionamento, execreverterá para o significado original:

  exec 3 < thisfile       # oops, overwrite the current program with command "3"

Existem várias maneiras de usá-las, no uso do ksh read -uou print -uno bash, por exemplo:

read <&3
echo stuff >&4
cdarke
fonte
22
também há outro uso que achei bastante útil e que vale a pena mencionar aqui, porque se refere a aplicativos da web python e parece algo entre as respostas (impressionantes) 2 e 3. Normalmente, eu executo os aplicativos da web wsgi (digamos django ou balão) através do supervisor chamando um gunicorn app: o último exigindo notoriamente algumas variáveis ​​de ambiente, é muito mais fácil e mais sustentável rodar o gunicorn a partir de um shell script que configura tudo e, eventualmente, exec gunicorndevolve o pid correto ao supervisor.
gru
1
Os médicos dizem que execpode ser usada para o redirecionamento:> Se o comando não for especificado, quaisquer redirecionamentos ter efeito no shell atual e o status de retorno é 0. Se houver um erro de redirecionamento, o status de retorno é 1. Mas como faz execrealmente funciona para alterar um descritor de arquivo? Por que esse comando específico é escolhido para esta tarefa? (Markdown está falhando agora?)
Ray
@ Ray: o melhor que posso fazer: pubs.opengroup.org/onlinepubs/009604599/utilities/exec.html . Se você precisar saber como, consulte o código-fonte do shell.
cdarke
7
Outro uso: Redirecione toda a saída de um script para um arquivo de log exec >.\logfilename.log 2>&1
Hogan
1
@ Carmageddon: &>é uma bashextensão (veja man bash) e seu exemplo é equivalente a exec >/var/log/userdata.log 2>&1. Em outras palavras, ele redireciona stdout e stderr para esse arquivo. Os comandos a seguir herdarão esses redirecionamentos, a menos que sejam redefinidos, mas serão executados.
cdarke
41

Apenas para aumentar a resposta aceita com uma breve resposta curta para iniciantes, você provavelmente não precisa exec.

Se você ainda estiver aqui, esperamos que a discussão a seguir revele o porquê. Quando você corre, digamos,

sh -c 'command'

você executa uma shinstância e inicia commandcomo filho dessa shinstância. Quando commandtermina, a shinstância também termina.

sh -c 'exec command'

executa uma shinstância e substitui essa shinstância pelocommand binário, e corre que em vez.

Obviamente, ambos são inúteis neste contexto limitado; você simplesmente quer

command

Existem algumas situações em que você deseja que o shell leia seu arquivo de configuração ou, de alguma forma, configure o ambiente como uma preparação para a execução command. Essa é praticamente a única situação em que exec commandé útil.

#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command

Isso faz algumas coisas para preparar o ambiente para que ele contenha o que é necessário. Feito isso, a shinstância não é mais necessária e, portanto, é uma otimização (menor) simplesmente substituir a shinstância pelo commandprocesso, em vez de tersh executá-la como um processo filho e aguardá-la, e sair assim que terminar.

Da mesma forma, se você deseja liberar o máximo de recursos possível para um comando pesado no final de um script de shell, convém exec esse comando como uma otimização.

Se algo obriga a correr, shmas você realmente queria executar outra coisa,exec something else é obviamente uma solução alternativa para substituir a shinstância indesejada (por exemplo, se você realmente deseja executar seu próprio spiffy em goshvez de shmas o seu não está listado em/etc/shells para que você possa especifique-o como seu shell de login).

O segundo uso de execpara manipular descritores de arquivo é um tópico separado. A resposta aceita cobre isso muito bem; para manter isso independente, vou adiar o manual para qualquer coisa que execseja seguida por um redirecionamento em vez de um nome de comando.

triplo
fonte
2
Resistindo à tentação de chamar sua própria concha espinhosa bush. Obviamente, isso se aplica a bashou geralmente a qualquer shell Unix popular; embora, como observa @anishsane , Bash secretamente otimize bash -c 'command'realizando exec command.
Tripleee
1
O código de saída do shell geralmente é o código de saída do último comando executado. Obviamente, se o shell falhar na execução ou na execução do comando, o status de saída do shell refletirá isso com um código de erro adequado.
Tripleee
2
@ JonathanLeffler Estou deliberadamente documentando um antipadrão que vejo nas perguntas dos novatos. Este foi solicitado por essa duplicata, mas eu já vi isso antes, então eu queria abordar isso especificamente.
Tripleee
2
@JonathanLeffler Menores ajustes na redação; isso é suficiente, você acha? Obrigado pelo feedback.
Tripleee
2
Obrigado - adicionei outro breve parágrafo sobre essa otimização. Não está realmente claro para mim se você tem outras objeções, ou se gostaria de explicar as coisas de um ângulo diferente.
Tripleee 26/07