Aqui, mostra-se o uso de ||
e &&
em uma única linha para concatenar a execução de comandos: Como posso verificar se há erros do apt-get em um script bash?
Estou tentando parar a execução de um script se uma determinada condição falhar,
por exemplo
false || echo "Obvious error because its false on left" && exit
Aqui ele imprime Obvious error because its false on the left
e sai do console, o que eu queria.
true || echo "This shouldn't print" && exit
Aqui, não há echo print, mas o exit
comando também é executado, ou seja, o console está fechado, o exit
comando não deve ser executado porque o comando echo à direita não foi executado? Ou, por padrão, é uma declaração considerada falsa no lado esquerdo de um &&
operador?
Edit: Eu deveria ter mencionado isso antes, meu objetivo era repetir o erro e sair se não estivesse claro. Para o meu caso específico de detectar erros ao agrupar condições usando && e ||, a resposta @ bodhi.zazen resolve o problema.
A resposta @takatakatek torna mais claro o controle de fluxo e os links do guia do bash são excelentes
A resposta do @muru tem uma boa explicação de por que não usar set -e, se você deseja que mensagens de erro personalizadas sejam exibidas com alternativas de uso de perl e trap, que eu acho que é uma maneira mais robusta e me vejo usando-a a partir do meu segundo script do bash!
fonte
Respostas:
Você provavelmente quer (como apontado por steeldriver)
Caso contrário, seu script está lendo uma condicional por vez
a ou be, em seguida, saia
Eu acho que você quer a ou (be sair)?
fonte
{ ... ; }
(como @steeldriver sugeriu), ou aexit
única sai do subshell, e o shell pai continua executando o script.O problema é que || e && pula apenas uma sub-rotina subsequente de uma cadeia de comandos quando a condição falha. Se você escrever uma estrutura de bloco completa, faz todo o sentido. O que você escreveu se torna o seguinte:
O que você quer é isso:
Quando você usa os operadores condicionais de atalho do Bash, é melhor evitar misturá-los. A lógica é muito mais fácil de entender enquanto você a escreve, e seus leitores apreciarão seu bom estilo.
fonte
if ... then ... elif ... else ... fi
blocos totalmente expressos . Eu suspeito que você pode não estar ciente de que o Bash não tem tipos booleanos verdadeiros vistos em idiomas mais sofisticados. Se o status de saída de um comando for 0 (zero), o Bash tratará isso como verdadeiro / bem-sucedido . Se o status de saída for diferente de zero, o Bash tratará isso como falso / falha .A maneira mais simples de falhar em erro é usar a
-e
opção do bash (set -e
ou/bin/bash -e
no shebang). No entanto, isso não facilita o envio de mensagens de erro personalizadas. Existem algumas expressões idiomáticas que podem simplificar:die
à la PerlPerl tem um muito conveniente
die
comando que imprime uma mensagem para stderr e levanta uma exceção, o que geralmente leva à terminação script. Você pode emular isso:trap
ERR
O
trap <command>
comando pode ser usado para executar um comando quando um sinal é recebido, ou ao sair do script (trap ... EXIT
), ou quando um comando retorna um erro (trap ... ERR
). Então, algo como:Então:
Em ambos os casos, sugiro usar pelo menos
exit 1
para indicar que o script falhou . Uma planícieexit
usará o status de saída do comando anterior, que nesses casos seriam os comandosecho
ouprintf
, que normalmente seriam bem-sucedidos. Salvar o status de saída do comando com falha, como fiz aqui, seria bom de se ter.fonte
Você pode experimentar um pouco ao iniciar o script com
O -e garante que o script saia no momento em que algo retornar falso. Uma falha específica pode ser evitada com
something || true
fonte