2016-12-07 12 views
7

Uwaga: istnieje wiele pytań dotyczących testowania zmiennej pojedynczej powłoki na tej stronie. To pytanie dotyczy testowania skryptu dla dowolnej niezdefiniowanej zmiennej.Jak sprawić, aby bash traktował niezdefiniowane zmienne jako błędy?

Można użyć niezdefiniowanej zmiennej w bashu nie widząc żadnego błędu przy wykonywaniu:

#!/bin/bash 

echo ${UNDEF_FILE} 
ls -l ${UNDEF_FILE} 

exit 0 

Znalazłem to bardzo podatny na błędy. Jeśli chcę zmienić nazwę zmiennej w dużym skrypcie lub usunąć tę zmienną, wszystkie poprzednie nieaktualne odwołania spowodują błędy w skrypcie. Czasami nie jest to oczywiste, aby debugować lub dowiedzieć się, kiedy jest już za późno.

Dlaczego jest to dozwolone? Czy istnieje sposób na oznaczenie niezdefiniowanych zmiennych?

+0

"Dlaczego" wracają do kompatybilności z muszlami z lat 1970-tych. Jeśli zależy Ci na najlepszych praktykach, w przeciwieństwie do historii, sprawdzanie statyczne - jak w przypadku http://shellcheck.net/, które jest również dostępne do pobrania [jako samodzielne narzędzie] (https://github.com/koalaman/shellcheck) - to twój przyjaciel. –

+1

Szczerze mówiąc, błędne interpretowanie niezdefiniowanych zmiennych może przerwać wiele typowych idiomów. '[[$ var]] & {echo" Robi coś z $ var "; } ', na przykład, zerwie z' set -u': W przeciwieństwie do 'set -e' (który powoduje tylko błędy, które nie są sprawdzane lub używane jako conditionals do błędów),' set -u' tworzy * co * odwołanie do niezdefiniowana zmienna i błąd. –

+0

(By the way - nazwy zmiennych all-caps są w przestrzeni zdefiniowanej przez POSIX dla zmiennych środowiskowych mających znaczenie dla powłoki lub systemu operacyjnego, przestrzeń nazw zmiennych zawierających co najmniej jeden mały znak jest zarezerwowana do użycia aplikacji. do wszystkich zmiennych powłoki, w przeciwieństwie do zmiennych środowiskowych, w związku z ustawianiem zmiennej powłoki dzielącej nazwę z zmienną środowiskową zastępującą tę ostatnią). –

Odpowiedz

9

Można użyć:

set -u 

na początku skryptu wyrzucić błąd podczas używania niezdefiniowanych zmiennych.

-u

Treat zmienne wyłączony i parametry inne niż specjalnymi parametrami „@” i „*” jako błąd podczas wykonywania ekspansji parametr. Jeśli próba ekspansji zostanie podjęta przy ustawieniu zmiennej lub parametru, powłoka drukuje komunikat o błędzie, a jeśli nie jest interaktywna, kończy pracę z niezerowym stanem.

+3

... jednak warto zauważyć, że użyteczność tego jest ... kontrowersyjna: wiele typowych idiomów zależy od niezdefiniowanych wartości rozszerzających się do łańcucha pustego, więc kod musi być jawnie zapisany dla zgodności 'set -u', jeśli chce, żeby tak było. –

+2

'set -o nounset' ma taki sam efekt jak' set -u' (w Bash), a niektórzy wolą go. – pjh

+1

Zobacz [Sprawdź, czy zmienna jest ustawiona w bashu podczas używania "set -o nounset"] (http://stackoverflow.com/q/7832080/4154375) aby znaleźć sposób na rozwiązanie typowych problemów spowodowanych użyciem 'set -u' lub 'set -o nounset'. – pjh

0

set -u jest opcja bardziej ogólne, ale jak zauważył w komentarzach innych odpowiedzi, istnieją problemy idiomatyczne pisanie skryptów powłoki z set -u w grze. Alternatywą jest tworzenie rozszerzeń parametrów, które powodują błąd, gdy określona zmienna nie jest ustawiona.

$ echo $foo 

$ echo $? 
0 
$ echo "${foo?:no foo for yoo}" 
bash: foo: :no foo for yoo 
$ echo $? 
1 

Ten błąd spowoduje zamknięcie nieinteraktywnej powłoki. Daje to szybki sposób zagwarantowania, że ​​warunek błędu nie pozwoli na kontynuowanie przepływu sterowania z nieokreśloną wartością. The spec nie wymaga powłoki interaktywnej do wyjścia, chociaż warto zauważyć, że nawet w powłoce interaktywnej bash powróci z wywołania funkcji, jeśli ten błąd wystąpi w funkcji.

Powiązane problemy