Alguém pode explicar quais são os usos do comando exec em scripts de shell com exemplos simples?
Alguém pode explicar quais são os usos do comando exec em scripts de shell com exemplos simples?
Respostas:
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-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 chamada ksh
. Enquanto isso funcionava, ele deixou um csh
processo disperso em execução, e o logout foi em dois estágios, o que poderia ser confuso. Então, mudamos para o exec 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 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 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 como ksh
e 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, exec
reverterá 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 -u
ou print -u
no bash
, por exemplo:
read <&3
echo stuff >&4
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 faz exec
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
&>
é uma bash
extensã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.
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 sh
instância e inicia command
como filho dessa sh
instância. Quando command
termina, a sh
instância também termina.
sh -c 'exec command'
executa uma sh
instância e substitui essa sh
instâ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 sh
instância não é mais necessária e, portanto, é uma otimização (menor) simplesmente substituir a sh
instância pelo command
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 a sh
instância indesejada (por exemplo, se você realmente deseja executar seu próprio spiffy em gosh
vez de sh
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 que exec
seja seguida por um redirecionamento em vez de um nome de comando.