Respostas:
Uma abordagem seria adicionar set -e
ao início do seu script. Isso significa (de help set
):
-e Exit immediately if a command exits with a non-zero status.
Portanto, se algum de seus comandos falhar, o script será encerrado.
Como alternativa, você pode adicionar exit
instruções explícitas nos possíveis pontos de falha:
command || exit 1
set -e
é a única maneira que sei fazer isso.
set -e
são sleep
( break
sendo um built-in especial, o script pode sair com falha na maioria dos shells, os comandos na if
esquerda ou à esquerda de &&
não são afetados set -e
, n=...
pode falhar se n
for somente leitura, mas depois que sairia do script set -e
também), de modo que a interpretação parece bastante improvável. Concordo que a pergunta está mal formulada.
Você pode sair de um script em qualquer lugar usando a palavra-chave exit
. Você também pode especificar um código de saída para indicar a outros programas que ou como o seu script falhou, por exemplo, exit 1
ou exit 2
etc. (por convenção, o código de saída 0 é bem-sucedido e qualquer coisa maior que 0 significa falha; no entanto, também por convenção, exit códigos acima de 127 são reservados para terminação anormal (por exemplo, por um sinal)).
A construção genérica para sair em caso de falha é
if [ failure condition ]; then
exit n
fi
com adequado failure condition
e n
. Mas em cenários específicos, você pode proceder de maneira diferente. Agora, no seu caso, interpreto sua pergunta de que, se alguma das cinco invocações gksu
falhar, você pretende sair. Uma maneira é usar uma função como esta
function try_command {
for i in 1 2 3 4 5 ; do
if gksu command ; then
return 0
fi
fi
exit 1
}
e, em seguida, chame o loop por try_command
.
Existem (mais) maneiras avançadas ou sofisticadas de como resolver sua pergunta. No entanto, a solução acima é mais acessível para iniciantes do que, digamos, a solução da Stephane.
attempt=0
until gksu command; do
attempt=$((attempt + 1))
if [ "$attempt" -gt 5 ]; then
exit 1
fi
done
exit
sai do script, a menos que seja chamado em um subshell. Se essa parte do script está em uma subshell, por exemplo, porque é dentro (...)
ou $(...)
ou parte de uma linha de tubo, então ele só vai sair que subshell .
Nesse caso, se você deseja que o script saia além do subshell, precisará chamar exit
esse subshell.
Por exemplo, aqui com 2 níveis aninhados de subshells:
(
life=hard
output=$(
echo blah
[ "$life" = easy ] || exit 1 # exit subshell
echo blih not run
) || exit # if the subshell exits with a non-zero exit status,
# exit as well with the same exit status
echo not run either
) || exit # if the subshell exits with a non-zero exit status,
# exit as well with the same exit status
Pode se tornar mais complicado se o subshell fizer parte de um pipeline. bash
tem um especial $PIPESTATUS
array, semelhante ao zsh
de $pipestatus
um que pode ajudá-lo aqui:
{
echo foo
exit 1
echo bar
} | wc -c
subshell_ret=${PIPESTATUS[0]}
if [ "$subshell_ret" -ne 0 ]; then
exit "$subshell_ret"
fi
A armadilha executará uma ação ao receber um sinal.
trap "echo EXIT; exit" 0
trap "echo HUP; exit" 1
trap "echo CTL-C; exit" 2
trap "echo QUIT; exit" 3
trap "echo ERR; exit" ERR
n=0
until [ $n -ge 5 ]
do
n=$[$n+1]
echo $n
sleep 3
done
Execute isso e deixe sair normalmente. Prende no sinal 0.
EXIT
Execute-o novamente e interrompa com ^ C. Ele intercepta o sinal 2 e o sinal 0.
CTL-C
EXIT
Um status de saída diferente de zero será interceptado no ERR
ERR
EXIT
set -e
. Realmente não se aplica aqui. O OP deseja sair do script após 5 tentativas fracassadas de executar o comando.