Uczę się, jak efektywnie używać różnych opcji set
w moim skrypcie i natrafiłem na set -u
, który wydaje się być idealny do wyjścia z mojego skryptu, jeśli zmienna nie jest ustawiona prawidłowo (np. usuwanie użytkowników). Zgodnie ze stroną man , set -u
i set -e
wykonuje następujące czynności …
-e Exit immediately if a command exits with a non-zero status. -u Treat unset variables as an error when substituting.
Utworzyłem skrypt testowy, aby przetestować tę funkcję, ale wygląda na to, że nie działa zgodnie z oczekiwaniami . Może ktoś mógłby lepiej wyjaśnić mi mój problem i gdzie źle interpretuję? Skrypt testowy znajduje się poniżej. Dziękuję.
set -e set -u testing="This works" echo $? echo ${testing} testing2= echo $? echo ${testing2} testing3="This should not appear" echo $? echo ${testing3}
Oczekuję, że skrypt wyświetli 0 i „To działa” , a następnie kończy się niepowodzeniem, ponieważ ${testing2}
jest nie ustawione.
Zamiast tego wyświetlane są 0 i „To działa” , a następnie 0 , a następnie 0 To nie powinno się pojawić
Czy ktoś może udzielić pewnej wiedzy? Dziękuję.
Komentarze
- Kontynuacja … czy istnieje sposób, aby ustawienie zmiennej na pusty łańcuch znaków było niedozwolone / powodowało błąd? ' nie zgaduję.
Odpowiedź
Od ” man Bash „:
Parametr jest ustawiany, jeśli przypisano mu wartość. Ciąg pusty jest prawidłową wartością. Po ustawieniu zmiennej można ją cofnąć tylko za pomocą wbudowanego polecenia unset.
Gdy wykonujesz testing2=
ustawiasz zmienną na ciąg pusty.
Zmień to na unset testing2
i spróbuj ponownie.
set -e
nie pomaga w tym przypadku, ponieważ przypisanie nigdy nie ma kodu zakończenia równego 1. Spróbuj tego, aby zobaczyć, że ostatnie wykonane polecenie (przypisanie) ma kod zakończenia równy 0 lub przeczytaj to pytanie :
$ false; a=""; echo $? 0
Uważam również, że użycie zestawu -e jest bardziej problem niż rozwiązanie.
To, co może spowodować błąd przy użyciu nieustawionych zmiennych, to set -u
:
#!/bin/bash set -u testing="This works" echo ${testing} unset testing2 echo ${testing2} testing3="This should not appear" echo ${testing3}
Wyświetli:
$ ./script.sh This works ./script.sh: line 9: testing2: unbound variable
Odpowiedź
testing2=
ustawia zmienną testing2
na pusty ciąg; zmienna faktycznie jest ustawiona .
Jednak gdybyś uruchomił echo $testing99
w interaktywnej powłoce Bash (bez ustawienia errexit
, tj. set -e
), wystąpiłby błąd:
bash: testing99: unbound variable
Poza tym
Podczas testowania skryptów właśnie teraz odkryłem, że interaktywna powłoka nie zawsze kończy działanie przy próbie rozwinięcia zmiennej, która nie została ustawiona , podczas gdy nieinteraktywna powłoka (uruchamiająca skrypt powłoki) zawsze kończy . Zgodnie ze stroną podręcznika POSIX dla set
:
-u Powłoka powinna napisać komunikat na standardowy błąd kiedy próbuje rozwinąć zmienną, która nie jest ustawiona i natychmiast kończy działanie. Interaktywna powłoka nie zakończy działania.
Interaktywna powłoka Bash nie zakończy działania, chyba że errexit
ma również został ustawiony. Z drugiej strony, interaktywna powłoka myślnika nie zostanie zamknięta – nawet jeśli set -e
został wcześniej uruchomiony.
Komentarze
- Jeśli myślnik nie kończy się z ustawionym -e; set u; nieustawiony aa; echo $ aa, to myślnik jest błędny.
- @schily Kiedy pierwszy raz to zauważyłem, pomyślałem, że autorzy myślnika wiedzieli lepiej ode mnie i że w specyfikacji POSIX mogły występować niejasności, ale po ponownym zaznaczone pubs.opengroup.org/onlinepubs/9699919799/utilities/… , zgadzam się, że to wygląda na błąd, w porządku.
- Jest prosta zasada: jeśli zarówno Korn Shell, jak i Bourne Shell zgadzają się, a inna implementacja powłoki ma odchylenie, druga powłoka zachowuje się niepoprawnie.