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;
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.
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).
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:
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?)
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.
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.
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.
Respostas:
o
exec
comando interno espelha funções no kernel, com base em uma família delasexecve
, geralmente chamada de C.exec
substitui o programa atual no processo atual, semfork
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;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:então agora não há shell para voltar. Mesmo se
appln-program
travar, o usuário final não pode acessar um shell, porque ele não está lá - oexec
substituiu.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 chamadaksh
. Enquanto isso funcionava, ele deixou umcsh
processo disperso em execução, e o logout foi em dois estágios, o que poderia ser confuso. Então, mudamos para oexec ksh
que 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).Apenas para salvar processos. Se chamarmos
prog1 -> 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
exec
usado 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
exec
shells comoksh
ebash
- usados para abrir descritores de arquivos. aqui estão alguns exemplos: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,
exec
reverterá para o significado original:Existem várias maneiras de usá-las, no uso do ksh
read -u
ouprint -u
nobash
, por exemplo:fonte
exec gunicorn
devolve o pid correto ao supervisor.exec
pode 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 fazexec
realmente funciona para alterar um descritor de arquivo? Por que esse comando específico é escolhido para esta tarefa? (Markdown está falhando agora?)exec >.\logfilename.log 2>&1
&>
é umabash
extensão (vejaman bash
) e seu exemplo é equivalente aexec >/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.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,
você executa uma
sh
instância e iniciacommand
como filho dessash
instância. Quandocommand
termina, ash
instância também termina.executa uma
sh
instância e substitui essash
instância pelocommand
binário, e corre que em vez.Obviamente, ambos são inúteis neste contexto limitado; você simplesmente quer
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 queexec command
é útil.Isso faz algumas coisas para preparar o ambiente para que ele contenha o que é necessário. Feito isso, a
sh
instância não é mais necessária e, portanto, é uma otimização (menor) simplesmente substituir ash
instância pelocommand
processo, 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,
sh
mas você realmente queria executar outra coisa,exec something else
é obviamente uma solução alternativa para substituir ash
instância indesejada (por exemplo, se você realmente deseja executar seu próprio spiffy emgosh
vez desh
mas o seu não está listado em/etc/shells
para que você possa especifique-o como seu shell de login).O segundo uso de
exec
para 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 queexec
seja seguida por um redirecionamento em vez de um nome de comando.fonte
bush
. Obviamente, isso se aplica abash
ou geralmente a qualquer shell Unix popular; embora, como observa @anishsane , Bash secretamente otimizebash -c 'command'
realizandoexec command
.