Mam skrypt powłoki Bash, który wywołuje wiele poleceń. Chciałbym, aby skrypt powłoki automatycznie wychodził z wartością zwracaną 1, jeśli którekolwiek z poleceń zwróci wartość niezerową.
Czy jest to możliwe bez wyraźnego sprawdzenia wyniku każdego polecenia?
na przykład
dosomething1
if [[ $? -ne 0 ]]; then
exit 1
fi
dosomething2
if [[ $? -ne 0 ]]; then
exit 1
fi
set -e
równieżset -u
(lubset -eu
).-u
kładzie kres idiotycznemu, chowającemu błędy zachowaniu, że można uzyskać dostęp do dowolnej nieistniejącej zmiennej i uzyskać pustą wartość bez diagnozy.Odpowiedzi:
Dodaj to na początku skryptu:
Spowoduje to natychmiastowe zamknięcie powłoki, jeśli zostanie zakończone proste polecenie z niezerową wartością wyjścia. Proste polecenie to dowolne polecenie, które nie jest częścią if, podczas lub do testu, lub częścią && lub || lista.
Zobacz stronę manuala bash (1) w wewnętrznym poleceniu „set”, aby uzyskać więcej szczegółów.
Osobiście uruchamiam prawie wszystkie skrypty powłoki za pomocą „set -e”. Naprawdę denerwujące jest utrzymywanie skryptu z uporem, gdy coś zawiedzie w środku i łamie założenia dla reszty skryptu.
źródło
bash script.sh
.set -e; tf() { false; }; tf; echo 'still here'
. Egzekucja jest przerywana, nawet bezset -e
wewnątrz ciałatf()
. Być może chciałeś powiedzieć, żeset -e
nie jest to dziedziczone przez podpowłoki , co jest prawdą.Aby dodać do zaakceptowanej odpowiedzi:
Pamiętaj, że
set -e
czasami to nie wystarczy, szczególnie jeśli masz rury.Załóżmy na przykład, że masz ten skrypt
... co działa zgodnie z oczekiwaniami: błąd
configure
przerywa wykonanie.Jutro dokonujesz pozornie trywialnej zmiany:
... a teraz to nie działa. Wyjaśniono to tutaj i podano obejście (tylko Bash):
źródło
pipefail
aby iść razemset -o
!Instrukcje if w twoim przykładzie są niepotrzebne. Po prostu zrób to w ten sposób:
Jeśli skorzystasz z porady Ville Laurikari i skorzystasz z niej, w
set -e
przypadku niektórych poleceń może być konieczne użycie tego:|| true
Uczyni rurociąg komenda matrue
wartość zwracana, nawet jeśli polecenie nie działa tak The-e
opcja nie zabije skrypt.źródło
set -e
nie jest bash-centric - jest obsługiwany nawet w oryginalnej powłoce Bourne Shell.Jeśli masz czyszczenie, które musisz zrobić przy wyjściu, możesz również użyć „pułapki” z pseudo-sygnałem ERR. Działa to tak samo, jak pułapkowanie INT lub dowolnego innego sygnału; bash rzuca ERR, jeśli jakieś polecenie zakończy się z niezerową wartością:
Lub, szczególnie jeśli używasz „set -e”, możesz uwięzić EXIT; pułapka zostanie wykonana po wyjściu skryptu z dowolnego powodu, w tym z normalnego końca, przerwania, wyjścia spowodowanego opcją -e itp.
źródło
$?
Zmienna jest rzadko potrzebne. Pseudo-idiomcommand; if [ $? -eq 0 ]; then X; fi
należy zawsze zapisywać jakoif command; then X; fi
.Przypadki, w których
$?
jest to wymagane, to konieczność sprawdzenia wielu wartości:lub kiedy
$?
trzeba ponownie wykorzystać lub w inny sposób zmanipulować:źródło
Uruchom go z
-e
lubset -e
na górze.Zobacz także
set -u
.źródło
help set
:-u
traktuje odniesienia do zmiennych nieustalonych jako błędy.set -u
czyset -e
nie jedno i drugie? @lumpynoseWyrażenie podobne do
przerwie przetwarzanie, gdy jedno z poleceń powróci z wartością niezerową. Na przykład następujące polecenie nigdy nie wyświetli polecenia „gotowe”:
źródło
powinno wystarczyć.
źródło
po prostu wrzucając kolejne w celach informacyjnych, ponieważ pojawiło się dodatkowe pytanie do wypowiedzi Marka Edgarsa, a oto dodatkowy przykład i dotyka ogólnie tematu:
który jest taki sam
cmd || exit errcode
jak ktoś pokazał.na przykład. Chcę się upewnić, że partycja nie jest zamontowana, jeśli jest zamontowana:
źródło
[[
cmd`]] `to nie to samo. To fałsz, jeśli dane wyjściowe polecenia są puste, a w przeciwnym razie prawda, niezależnie od statusu wyjścia polecenia.