Eu não entendo o comando bash exec
. Eu o vi usado dentro de scripts para redirecionar toda a saída para um arquivo (como visto neste ). Mas não entendo como funciona ou o que faz em geral. Eu li as páginas de manual, mas não as entendo.
107
exec
de uma maneira especial, que pode ser explicada de maneira muito mais simples: escreverei uma resposta.Respostas:
man bash
diz:As duas últimas linhas são importantes: se você executar
exec
por si só, sem um comando, simplesmente fará os redirecionamentos se aplicarem ao shell atual. Você provavelmente sabe que quando executacommand > file
, a saída decommand
é gravada emfile
vez de no seu terminal (isso é chamado de redirecionamento ). Se você executarexec > file
, o redirecionamento se aplicará a todo o shell: qualquer saída produzida pelo shell é gravada nofile
lugar do terminal. Por exemplo aquiPrimeiro inicio um novo
bash
shell. Então, neste novo shell, eu corroexec > file
, para que toda a saída seja redirecionada parafile
. De fato, depois disso, eu corro,date
mas não recebo saída, porque a saída é redirecionada parafile
. Então saio do shell (para que o redirecionamento não se aplique mais) e vejo que, defile
fato, contém a saída dodate
comando que executei anteriormente.fonte
exec
serve para substituir também o processo atual do shell por um comando, para que o pai siga um caminho e o filho seja dono do pid. Isso não é apenas para redirecionamento. Por favor, adicione esta informaçãoexec nginx <various nginx arguments>
. Isso significa que o nginx assume o controle do script bash e agora o nginx é o principal processo de execução do contêiner, não o script. Presumo que isso seja apenas para limpeza, a menos que alguém saiba uma razão mais concreta para isso?gnome-terminal
, que pelo menos em 14.04 tinha um script de wrapper para configurar argumentos. E esse é o único objetivo, realmente - definir artes e ambiente. Outro caso seria limpar - matar a instância anterior de um processo primeiro e lançar um novoexec
exemplo semelhante aonginx
exemplo dado por @LukeGriffiths é o~/.vnc/xstartup
script quevncserver
usa para configurar um processo de servidor VNC e, em seguida,exec gnome-session
ouexec startkde
e assim por diante.exec
um script de inicialização de contêiner é que o PID 1, o ENTRYPOINT do contêiner, tem um significado especial no Docker. É um processo principal que recebe sinais e, quando existe, o contêiner também sai.exec
apenas uma maneira de removersh
essa cadeia de comando e tornar o daemon o principal processo do contêiner.exec
é um comando com dois comportamentos muito distintos, dependendo se pelo menos um argumento é usado com ele ou se nenhum argumento é usado.Se pelo menos um argumento for passado, o primeiro será usado como um nome de comando e
exec
tentará executá-lo como um comando passando os argumentos restantes, se houver, para esse comando e gerenciando os redirecionamentos, se houver.Se o comando transmitido como primeiro argumento não existir, o shell atual, não apenas o comando exec, sai por engano.
Se o comando existe e é executável, ele substitui o shell atual. Isso significa que, se
exec
aparecer em um script, as instruções após a chamada exec nunca serão executadas (a menos queexec
esteja em um subshell).exec
nunca retorna. As armadilhas do shell como "EXIT" também não serão acionadas.Se nenhum argumento for passado,
exec
será usado apenas para redefinir os descritores atuais do arquivo shell. O shell continua após oexec
, ao contrário do caso anterior, mas a entrada, saída, erro ou qualquer outro descritor de arquivo padrão foi redirecionado.Se alguns dos redirecionamentos forem usados
/dev/null
, qualquer entrada dele retornará EOF e qualquer saída será descartada.Você pode fechar os descritores de arquivos usando
-
como origem ou destino, por exemploexec <&-
. A leitura ou gravação subsequente falhará.Aqui estão dois exemplos:
Este script produzirá "foo" como o comando cat, em vez de aguardar a entrada do usuário, como faria no caso usual, receberá sua entrada do arquivo / tmp / bar que contém foo.
Este script será exibido
4
(o número de bytes em / tmp / bar) e será encerrado imediatamente. Ocat
comando não será executado.fonte
/dev/null
, portanto, as gravações ainda são bem-sucedidas e as leituras retornam EOF.close(2)
em um fd faria com que as chamadas do sistema de leitura / gravação retornassem erros, e você faz issoexec 2>&-
por exemplo.exec 3</dev/null;
ls -l /proc/self/fd
observe que o fd 3 será aberto somente para leitura em / dev / null. Em seguida, feche-o novamente comexec 3<&-
e você poderá ver (comls -l /proc/$$/fd
novamente) que seu processo de shell não tem mais fd 3. (fechar stdin comexec <&-
pode ser útil em scripts, mas de forma interativa, é um logout.)exec
resposta mais votada atualmente falam apenas sobre um caso de uso e a outra resposta de g_p fala apenas sobre o outro caso de uso. E essa resposta é boa e concisa / legível para um assunto tão complexo.Para entender
exec
você precisa primeiro entenderfork
. Eu estou tentando mantê-lo curto.Quando você chega a uma bifurcação na estrada, geralmente tem duas opções. Os programas Linux alcançam essa bifurcação quando atendem a uma
fork()
chamada do sistema.Programas normais são comandos do sistema que existem em um formulário compilado no seu sistema. Quando esse programa é executado, um novo processo é criado. Esse processo filho tem o mesmo ambiente que seu pai, apenas o número de identificação do processo é diferente. Este procedimento é chamado de bifurcação .
exec
é usado.exec
substituirá o conteúdo do processo atualmente em execução pelas informações de um programa binário.fonte
exec
pode redirecionar uma saída de script, como no link que eu postei?Em
bash
, se você fizerhelp exec
:O bit relevante:
exec
é um shell embutido , que é o equivalente do shell daexec
família de chamadas de sistema das quais o G_P fala (e cujas páginas de manual você parece ter lido). Ele apenas possui a funcionalidade mandatada pelo POSIX de afetar o shell atual se nenhum comando for especificado.fonte