Odpowiedzi:
Jednym z podejść byłoby dodanie set -e
na początku skryptu. Oznacza to (z help set
):
-e Exit immediately if a command exits with a non-zero status.
Jeśli więc któreś z twoich poleceń się nie powiedzie, skrypt zakończy działanie.
Alternatywnie możesz dodać wyraźne exit
instrukcje w możliwych punktach awarii:
command || exit 1
set -e
to jedyny sposób, w jaki mogę to zrobić.
set -e
to sleep
( break
specjalne wbudowanie spowoduje, że skrypt zakończy działanie po awarii w większości powłok, na komendy w if
lub po lewej stronie &&
nie ma wpływu set -e
, n=...
może się nie powieść, jeśli n
jest tylko do odczytu, ale wtedy bez niego set -e
również wyjdzie ze skryptu ), więc interpretacja wydaje się mało prawdopodobna. Zgadzam się, że pytanie jest źle sformułowane.
Możesz wyjść ze skryptu w dowolnym miejscu za pomocą słowa kluczowego exit
. Możesz także podać kod zakończenia, aby wskazać innym programom, że skrypt nie powiódł się, np. exit 1
Lub exit 2
itp. (Zgodnie z konwencją kod wyjścia 0 oznacza sukces, a wartość większa od 0 oznacza niepowodzenie; jednak również zgodnie z konwencją wyjście kody powyżej 127 są zarezerwowane dla nienormalnego zakończenia (np. przez sygnał)).
Ogólna konstrukcja wyjścia w przypadku awarii jest
if [ failure condition ]; then
exit n
fi
z odpowiednim failure condition
i n
. Ale w określonych scenariuszach możesz postępować inaczej. Teraz dla twojej sprawy interpretuję twoje pytanie, że jeśli któreś z pięciu wezwań gksu
nie powiedzie się, to masz zamiar wyjść. Jednym ze sposobów jest użycie takiej funkcji
function try_command {
for i in 1 2 3 4 5 ; do
if gksu command ; then
return 0
fi
fi
exit 1
}
a następnie wywołaj pętlę przez try_command
.
Istnieją (bardziej) zaawansowane lub wyrafinowane sposoby rozwiązania twojego pytania. Jednak powyższe rozwiązanie jest bardziej dostępne dla początkujących niż, powiedzmy, rozwiązanie Stephane.
attempt=0
until gksu command; do
attempt=$((attempt + 1))
if [ "$attempt" -gt 5 ]; then
exit 1
fi
done
exit
kończy skrypt, chyba że jest wywoływany w podpowłoce. Jeśli ta część skryptu jest w podpowłoce, na przykład dlatego, że znajduje się wewnątrz (...)
lub $(...)
lub część rurociągiem, wtedy wyjść tylko , że powłoki w tle .
W takim przypadku, jeśli chcesz, aby skrypt zakończył działanie oprócz podpowłoki, musisz wywołać exit
wyjście z tej podpowłoki.
Na przykład tutaj z 2 zagnieżdżonymi poziomami podpowłoki:
(
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
Może stać się trudniejsze, jeśli podpowłoka jest częścią potoku. bash
posiada specjalną $PIPESTATUS
tablicę, podobną do zsh
„s $pipestatus
jednym, które mogą Ci pomóc tutaj:
{
echo foo
exit 1
echo bar
} | wc -c
subshell_ret=${PIPESTATUS[0]}
if [ "$subshell_ret" -ne 0 ]; then
exit "$subshell_ret"
fi
Pułapka wykona akcję po otrzymaniu sygnału.
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
Uruchom to i pozwól mu wyjść normalnie. Zatrzymuje sygnał 0.
EXIT
Uruchom go ponownie i przerwij za pomocą ^ C. Przechwytuje sygnał 2 i sygnał 0.
CTL-C
EXIT
Niezerowy status wyjścia będzie pułapką na ERR
ERR
EXIT
set -e
. Jednak tak naprawdę nie ma tutaj zastosowania. OP chce wyjść ze skryptu po 5 nieudanych próbach uruchomienia polecenia.