użycie set -u nie działa zgodnie z oczekiwaniami

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.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *