Eu sou um noob em scripts de shell. Quero imprimir uma mensagem e sair do meu script se um comando falhar. Eu tentei:
my_command && (echo 'my_command failed; exit)
mas não funciona. Ele continua executando as instruções após esta linha no script. Estou usando o Ubuntu e o bash.
linux
bash
exit
exitstatus
user459246
fonte
fonte
Respostas:
Experimentar:
Quatro mudanças:
&&
para||
{ }
no lugar de( )
;
depoisexit
e{
antes e antes}
Como você deseja imprimir a mensagem e sair somente quando o comando falhar (sai com um valor diferente de zero), você
||
não precisa de um&&
.será executado
cmd2
quandocmd1
for bem-sucedido (valor de saída0
). Enquanto queserá executado
cmd2
quandocmd1
falhar (valor de saída diferente de zero).Usar
( )
faz com que o comando dentro deles seja executado em um sub shell e chamar umexit
de lá faz com que você saia do sub shell e não do shell original; portanto, a execução continua no shell original.Para superar esse uso
{ }
As duas últimas alterações são exigidas pelo bash.
fonte
{ (>&2 echo 'my_command failed') ; exit 1; }
As outras respostas abordaram bem a pergunta direta, mas você também pode estar interessado em usá-lo
set -e
. Com isso, qualquer comando que falhar (fora de contextos específicos, comoif
testes) fará com que o script seja interrompido. Para certos scripts, é muito útil.fonte
set -e
possui um longo e misterioso conjunto de regras sobre quando funciona e quando não funciona. (Se alguém executarif yourfunction; then ...
,set -e
nunca será acionado por dentroyourfunction
ou por qualquer coisa que ele chamar, porque esse código é considerado "verificado"). Consulte a seção de exercícios do BashFAQ # 105 , discutindo esta e outras armadilhas (algumas das quais se aplicam apenas a versões específicas do shell, portanto, você deve testar todos os lançamentos que podem ser usados para executar seu script).Observe também que o status de saída de cada comando é armazenado na variável do shell $ ?, que você pode verificar imediatamente após a execução do comando. Um status diferente de zero indica falha:
fonte
echo "Just finished step A"
, sem saber que issoecho
substituiu o$?
que seria verificado mais tarde.Se você deseja esse comportamento para todos os comandos do seu script, basta adicionar
no início do script. Esse par de opções informa ao interpretador bash para sair sempre que um comando retornar com um código de saída diferente de zero.
Isso não permite que você imprima uma mensagem de saída.
fonte
trap
comando interno do bash.set -o pipefail
pode não ser o comportamento desejado. Ainda obrigado por apontar!set -e
não é de todo confiável, consistente ou previsível! Para convencer-se disso, reveja a seção exercícios de BashFAQ # 105 , ou a tabela comparando os comportamentos dos diferentes conchas na in-ulm.de/~mascheck/various/set-eEu hackeei o seguinte idioma:
Preceda cada comando com um eco informativo e siga cada comando com a mesma
if [ $? -ne 0 ];...
linha. (Obviamente, você pode editar essa mensagem de erro, se desejar.)fonte
if ! javac *.java; then ...
- por que se preocupar$?
?Fornecido
my_command
é canonicamente projetado, ou seja , retorna 0 quando for bem-sucedido, então&&
é exatamente o oposto do que você deseja. Você quer||
.Observe também que
(
não me parece correto no bash, mas não posso tentar de onde estou. Conte-me.fonte
Você também pode usar, se quiser preservar o status do erro de saída, e ter um arquivo legível com um comando por linha:
Isso, no entanto, não imprimirá nenhuma mensagem de erro adicional. Mas, em alguns casos, o erro será impresso pelo comando com falha de qualquer maneira.
fonte
exit $?
; apenasexit
usa$?
como seu valor padrão.O
trap
shell embutido permite capturar sinais e outras condições úteis, incluindo falha na execução de comandos (ou seja, um status de retorno diferente de zero). Portanto, se você não quiser testar explicitamente o status de retorno de cada comando único, poderá dizertrap "your shell code" ERR
e o código do shell será executado sempre que um comando retornar um status diferente de zero. Por exemplo:trap "echo script failed; exit 1" ERR
Observe que, como em outros casos de captura de comandos com falha, os pipelines precisam de tratamento especial; o acima não vai pegar
false | true
.fonte