Mam skrypt powłoki z zagnieżdżonymi pętlami i właśnie odkryłem, że „exit” tak naprawdę nie kończy skryptu, a jedynie bieżącą pętlę. Czy istnieje inny sposób całkowitego wyjścia ze skryptu w przypadku wystąpienia określonego błędu?
Nie chcę używać „zestawu -e”, ponieważ występują dopuszczalne błędy i wymagałoby to zbyt dużego przepisywania.
W tej chwili używam kill do ręcznego zabicia procesu, ale wydaje się, że powinien istnieć lepszy sposób na zrobienie tego.
bash -c 'for x in y z; do exit; done; echo "This never gets printed"'
.Odpowiedzi:
Twoim problemem nie są same zagnieżdżone pętle. Chodzi o to, że jedna lub więcej wewnętrznych pętli działa w podpowłoce .
To działa:
wynik:
To przedstawia opisany problem:
wynik:
Oto rozwiązanie; musisz przetestować zwracaną wartość wewnętrznych pętli, które działają w podpowłokach:
Uwaga na test:
[[ $? != 0 ]] && exit $?
wynik:
Edycja: Aby sprawdzić, w jakiej podpowłoce się znajdujesz, zmodyfikuj skrypt „answer”, aby poinformować Cię, jaki jest identyfikator procesu bieżącej powłoki. UWAGA: Działa to tylko w bash 4:
wynik:
Zmienne „i” i „j” zostały udostępnione dzięki uprzejmości Fortran. Miłego dnia. :-)
źródło
bash --version
w wierszu poleceń.Wcześniejsza odpowiedź sugeruje użycie
[[ $? != 0 ]] && exit $?
jednak nie będzie to dość pracy zgodnie z oczekiwaniami, ponieważ[[ $? != 0 ]]
badanie zostanie zresetowany$?
do zera, co oznacza, że chociaż skrypt wczesne wyjście zgodnie z oczekiwaniami, to będzie zawsze wyjście z kodem 0 (jak nie oczekuje) . Lepiej byłoby też użyć-ne
numerycznego testu porównawczego niż!=
testu porównania łańcuchów. Dlatego IMHO lepszym rozwiązaniem jest użycie:ponieważ zapewni to prawidłowe ustawienie faktycznego kodu wyjścia.
źródło
Możesz użyć
break
.Od
help break
:Aby wyjść z trzech otaczających pętli, tj. Jeśli masz dwie zagnieżdżone pętle w jednej głównej, użyj tego, aby wyjść ze wszystkich:
źródło
for((i=0;i<3;i++));do echo A;for((j=0;j<2;j++));do echo B;break 2;done;done
exit
kończy całą powłokę lub bieżącą podpowłokę:źródło