Executa “exec echo some; teste de eco ”no bash nunca imprime“ algum teste ”?

5

A execução de exec echo "some "; echo "test" no bash nunca imprime "algum teste"?

Eu buscaria confirmação para esta pergunta, já que estou escrevendo um pequeno script de shell e gostaria que ele não contivesse nada após o comando exec ter sido chamado.

Eu acho que não precisaria se preocupar, como eu entendo, depois de consultar:

  • man 3 exec
  • man 1p exec

Os scripts de shell, quando executados pelo shell, farão

  1. o shell executa o programa exec , que
  2. usa as chamadas do sistema exec*** family que substituem o shell / bash que executou o script, impedindo ações adicionais do shell (que foi "substituído")

Como exposto anteriormente, o objetivo principal desta questão é buscar a confirmação do meu raciocínio para evitar que algo no script ocorra depois que o exec (como echo test ) seja executado.

Eu apreciaria uma resposta geral (POSIX), na medida do possível, mas apenas no caso de particularidades eu estou mais interessado em GNU / Linux e GNU / Bash

    
por humanityANDpeace 26.11.2017 / 11:11

3 respostas

3

exec sempre termina o script if executa um comando e o faz com êxito (não relacionado ao código de saída do comando, mas ao início).

exec pode ser executado sem um comando de uma maneira muito útil: Para redirecionar permanentemente os descritores de arquivos:

exec 3>/path/to/file

Se o comando não puder ser iniciado, o comportamento do shell dependerá da configuração. bash sai por padrão.

Pode ser melhor usar uma função:

safe_exec () {
    cmd="$1"
    if test -z "$cmd" || ! test -f "$cmd" || ! test -x "$cmd"; then
        exit 1
    else
        exec "$@"
    fi
}

safe_exec echo "some "; echo "test"
    
por 26.11.2017 / 13:05
6

Certo, se exec for bem-sucedido, ele substitui o shell atual, portanto os comandos a seguir não são errados.

No entanto, pelo menos no Bash , o shell também sai se o exec falha :

exec [-cl] [-a name] [command [arguments]]

If command is supplied, it replaces the shell without creating a new process. [...] If command cannot be executed for some reason, a non-interactive shell exits, unless the execfail shell option is enabled. In that case, it returns failure.

Assim, mesmo algo como bash -c 'exec /bin/nosuchfile; echo foo' apenas imprimirá uma mensagem de erro sobre o arquivo de programa ausente. Para lidar com o erro no script, você precisaria de algo como

#!/bin/bash
shopt -s execfail
exec /someprogram
echo whoops, it failed

Mas você ainda recebe a mensagem de erro de exec . Se você colocar um redirecionamento no exec , ele permanecerá em vigor se o script continuar após o exec ter falhado.

    
por 26.11.2017 / 13:22
5

O exec builtin (com um argumento de comando¹) substitui o processo do shell². Nenhum código subseqüente no processo do shell é executado.

Assim, a única maneira que exec echo "some "; echo "test" imprimiria some text seria se houvesse um comando executável chamado echo no PATH, e esse executável imprimiu some text em vez de some . Isso não pode acontecer em circunstâncias normais, onde o executável echo se comporta como seria de esperar de um comando chamado echo .

Se não houver um arquivo executável chamado echo no PATH ou se ele falhar, o exec exibirá uma mensagem de erro e sairá do shell. Mesmo nesse caso, echo "test" não é executado.

¹ exec sem um argumento de comando é um animal diferente. Não substitui o processo shell, apenas aplica redirecionamentos.
² Em um subshell, somente o subshell é afetado, o shell pai continua funcionando normalmente.

    
por 26.11.2017 / 13:18

Tags