Obserwuję dziwne zachowanie podczas używania set -e( errexit), set -u( nounset) wraz z pułapkami ERR i EXIT. Wydają się powiązane, więc postawienie ich w jednym pytaniu wydaje się rozsądne.
1) set -unie uruchamia pułapek ERR
Kod:
#!/bin/bash trap 'echo "ERR (rc: $?)"' ERR set -u echo ${UNSET_VAR}- Oczekiwany: pułapka ERR zostaje wywołana, RC! = 0
- Faktycznie: pułapka ERR nie jest wywoływana, RC == 1
- Uwaga:
set -enie zmienia wyniku
2) Użycie set -eukodu wyjścia w pułapce WYJŚCIA wynosi 0 zamiast 1
Kod:
#!/bin/bash trap 'echo "EXIT (rc: $?)"' EXIT set -eu echo ${UNSET_VAR}- Oczekiwany: wywoływana jest pułapka WYJŚCIA, RC == 1
- Faktycznie: pułapka EXIT jest wywoływana, RC == 0
- Uwaga: Podczas używania
set +eRC == 1. Pułapka WYJŚCIA zwraca prawidłowe RC, gdy jakiekolwiek inne polecenie zgłosi błąd. - Edycja: Istnieje post SO na ten temat z interesującym komentarzem sugerującym, że może to być związane z używaną wersją Bash. Testowanie tego fragmentu w Bash 4.3.11 daje RC = 1, więc to lepiej. Niestety aktualizacja Bash (z wersji 3.2.51) na wszystkich hostach nie jest w tej chwili możliwa, dlatego musimy wymyślić inne rozwiązanie.
Czy ktoś może wyjaśnić którekolwiek z tych zachowań?
Przeszukiwanie tych tematów nie było bardzo udane, co jest dość zaskakujące, biorąc pod uwagę liczbę postów dotyczących ustawień i pułapek Basha. Jest jednak jeden wątek na forum , ale wniosek jest raczej niezadowalający.
set -ei set -uoba są zaprojektowane specjalnie do zabijania skryptów powłoki. Używanie ich w warunkach, które mogą uruchomić ich aplikację, zabije skryptowaną powłokę. Nie ma poruszanie się, że z wyjątkiem do nie korzystania z nich, a zamiast tego testu dla tych warunkach, gdy mają one zastosowanie w sekwencji kodu. Zasadniczo możesz napisać dobry kod powłoki lub użyć set -eu.
-unie wyzwalać pułapki ERR (jest to błąd, więc nie powinien wyzwalać pułapki) lub kod błędu to 0 zamiast 1. ten drugi wydaje się być błędem, który został już naprawiony w późniejszej wersji, więc to tyle. Ale pierwsza część jest dość trudna do zrozumienia, jeśli nie zdajesz sobie sprawy, że błędy w ocenie powłoki (rozszerzenie parametrów) i rzeczywiste błędy w poleceniach wydają się być dwiema różnymi rzeczami. Jeśli chodzi o rozwiązanie, cóż, jak zasugerowałeś, staram się teraz unikać -eui sprawdzać ręcznie, kiedy jest to konieczne.
(set -u; : $UNSET_VAR)i podobne. Tego rodzaju rzeczy też mogą być dobre - od &&czasu do czasu możesz zrzucić wiele rzeczy : (set -e; mkdir dir; cd dir; touch dirfile)jeśli dostaniesz mój dryf. Po prostu są to kontrolowane konteksty - kiedy ustawisz je jako opcje globalne, tracisz kontrolę i stajesz się kontrolowany. Zazwyczaj są jednak bardziej wydajne rozwiązania.
bashzerwał ze standardem i zaczął umieszczać pułapki w podpowłokach. Pułapka ma być wykonana w tym samym środowisku, z którego nastąpił powrót, alebashnie zrobiła tego od dłuższego czasu.