2016-12-07 2 views
7

Hinweis: Es gibt viele Fragen zum Testen einer einzelnen Shell-Variablen auf dieser Site. In dieser Frage wird ein Skript für eine undefinierte Variable getestet.Wie kann ich bash behandeln undefinierte Variablen als Fehler?

Sie können eine undefinierte Variable in bash verwenden, ohne einen Fehler bei der Ausführung zu sehen:

#!/bin/bash 

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

exit 0 

Ich habe dies sehr fehleranfällig gefunden. Wenn ich den Namen einer Variablen in einem großen Skript ändern oder diese Variable entfernen möchte, verursachen alle vorherigen veralteten Referenzen Fehler im Skript. Manchmal ist dies nicht offensichtlich zu debuggen oder Sie finden heraus, wenn es zu spät ist.

Warum ist das erlaubt? Gibt es eine Möglichkeit, undefinierte Variablen zu kennzeichnen?

+0

Die "Warum" gehen auf die Kompatibilität mit Shells der 1970er Jahre zurück. Wenn Sie sich für Best Practices interessieren, im Gegensatz zu history, static checking - wie bei http://shellcheck.net/, das auch als Download verfügbar ist [als eigenständiges Tool] (https://github.com/koalaman/shellcheck) - ist dein Freund hier. –

+1

Ehrlich gesagt, wird die Erweiterung von undefinierten Variablen fehlerhaft viele gängige Idiome brechen. '[[$ var]] & {echo" Etwas mit $ var machen "; } 'wird zum Beispiel mit' set -u' brechen: Im Gegensatz zu 'set -e' (das nur Fehler macht, die nicht geprüft oder als Bedingung in Fehler verwendet werden), macht' set -u' * jeden * Verweis auf eine undefinierte Variable ein Fehler. –

+0

(Übrigens - All-Caps-Variablennamen sind im Space von POSIX für Umgebungsvariablen mit der Bedeutung der Shell oder des Betriebssystems definiert; der Namespace von Variablen mit mindestens einem Kleinbuchstaben ist für die Anwendung reserviert für alle Shell-Variablen, im Gegensatz zu nur den Umgebungsvariablen, da eine Shell-Variable einen Namen mit einer Umgebungsvariablen teilt, die diese überschreibt. –

Antwort

9

können Sie verwenden:

set -u 

zu Beginn des Skripts einen Fehler zu werfen, wenn undefinierte Variablen.

-u

Treat ungesetzt Variablen und andere Parameter als die speziellen Parameter "@" und "*" als ein Fehler, wenn der Parameter Expansion durchführt. Wenn die Erweiterung für eine nicht gesetzte Variable oder einen Parameter versucht wird, gibt die Shell eine Fehlermeldung aus, und wenn sie nicht interaktiv ist, wird sie mit einem Status ungleich Null beendet.

+3

... aber es ist erwähnenswert, dass der Nutzen davon ... kontrovers ist: Viele gebräuchliche Idiome hängen von undefinierten Werten ab, die sich zu einer Null-Zeichenkette erweitern, so dass Code explizit für 'set -u' Kompatibilität geschrieben werden muss will es so sein. –

+2

'Set -o Nomenset' hat den gleichen Effekt wie' Set -u' (in Bash), und einige Leute bevorzugen es. – pjh

+1

Siehe [Prüfen Sie, ob eine Variable in bash gesetzt ist, wenn Sie »set -o Nomenset«] (http://stackoverflow.com/q/7832080/4154375) verwenden, um mit allgemeinen Problemen umzugehen, die durch die Verwendung von 'set -u' oder verursacht werden 'Satz -o Nomenset'. – pjh

0

set -u ist die allgemeinere Option, aber wie in anderen Antworten Kommentare darauf hingewiesen, gibt es Probleme idiomatischen Shell-Skripte mit set -u im Spiel zu schreiben. Eine Alternative besteht darin, Parametererweiterungen zu erstellen, die zu einem Fehler führen, wenn eine bestimmte Variable nicht festgelegt ist.

$ echo $foo 

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

Dieser Fehler führt dazu, dass eine nicht interaktive Shell beendet wird. Auf diese Weise können Sie schnell garantieren, dass eine Fehlerbedingung den Steuerungsfluss nicht mit einem nicht definierten Wert fortsetzen kann. The spec erfordert keine interaktive Shell zum Beenden, obwohl es bemerkenswert ist, dass selbst in einer interaktiven Shell bash von einem Funktionsaufruf zurückkehrt, wenn dieser Fehler in einer Funktion auftritt.

Verwandte Themen