web-dev-qa-db-de.com

Shell-Skript - Skript wird beendet, wenn die Variable null oder leer ist

Ich erwarte, die unten stehende Variable in meinem Bash-Skript zu verwenden. Falls dies jedoch leer oder null ist, was wäre der beste Weg, um damit umzugehen und das Skript zu beenden.

tag=$1  

Ich sehe Antworten mit 'set -u'. Ich weiß, dass dies funktionieren wird, aber ist dies für die Produktionsumgebung gut?

12

Es gibt einen integrierten Operator, der das Setzen einer Variablen erfordert. Dadurch wird das Skript beendet, wenn dies nicht der Fall ist.

tag=${1?Need a value}

Normalerweise wird dies mit dem : no-op am Anfang des Skripts verwendet.

: ${1?Need a value}

Die Verschmelzung von "nicht festgelegt oder leer" ist etwas anders. Es gibt kein ähnliches Konstrukt für das Beenden eines leeren, aber gesetzten Werts. Sie können jedoch leicht die zugehörige Syntax ${var:-default} verwenden, die sich zu $var erweitert, wenn sie gesetzt und nichtleer ist, andernfalls default. Es gibt auch ${var-default}, das nur default erzeugt, wenn die Variable nicht richtig gesetzt ist.

Dies kann besonders nützlich sein, wenn Sie wollen set -u verwenden, jedoch mit einer möglicherweise nicht festgelegten Variablen zurechtkommen müssen:

case ${var-} in '') echo "$0: Need a value in var" >&2; exit 1;; esac

Ich ziehe case etwas lieber als if [ "${var-}" = '' ] vor, hauptsächlich, weil ich so keine Anführungszeichen um ${var-} und den ärgerlichen Fall eines Werts in $var schreiben muss, der als Option für [ interpretiert wird und eine Fehlermeldung anzeigt, wenn Sie es am wenigsten erwarten. (In Bash hat [[ diese Probleme nicht; ich bleibe jedoch lieber bei POSIX Shell, wenn ich kann.)

23
tripleee

Wenn Sie testen möchten, dass eine Variable nicht leer ist, können Sie Folgendes tun:

if [ -z "$tag" ]; then
    exit 1
fi

Aus dem Handbuch für test:

-z STRING

die Länge von STRING ist Null

Wenn Sie die Positionsargumente für das Skript verwenden, können Sie auch die Anzahl der Argumente testen, die Sie erhalten, indem Sie $# betrachten.

14
Micah Smith

Niemand hat die :?-Option vorgeschlagen.

Wenn Sie sicherstellen möchten, dass die Variable festgelegt ist und nicht null ist:

SEARCH_PATH=${DAYS_TO_KEEP:?Must provide DAYS_TO_KEEP.}

Wird sofort mit Code 2 beendet und eine Nachricht ausgegeben:

/entrypoint.sh: line 17: SEARCH_PATH: Must provide DAYS_TO_KEEP.
5
Pav K.

Ich bin nicht sicher, ob Sie ermitteln möchten, ob eine Variable unset oder empty ist. Dies sind zwei verschiedene Dinge. Insbesondere kann eine Variable gesetzt werden, aber leer sein:

$ var=""
$ if [ -z "$var" ]; then echo empty; fi
$ empty

Das Gleiche geht hier vor:

#!/usr/bin/env bash

set -u
echo $1

Prüfung:

$ ./test.sh
./test.sh: line 4: $1: unbound variable
$ ./test.sh ""

$

Oder hier:

#!/usr/bin/env bash

tag=${1?Need a value}
echo $tag

Prüfung:

$ ./se.sh
./se.sh: line 3: 1: Need a value
$ ./se.sh ""

$

Andere Plakate haben korrekte Wege gezeigt, um eine nicht festgelegte und leere Variable zu erkennen. Ich persönlich mag diese Art, leere und nicht festgelegte Variablen zu erkennen:

#!/usr/bin/env bash

if [ "$1"A = A ]
then
    echo variable is empty or unset
fi

Prüfung:

$ ./empty.sh ""
variable is empty or unset
$ ./empty.sh
variable is empty or unset
$ ./empty.sh 1
$
3

Mir gefiel eher, wie Perl "Die" verwendet und es ist leicht, etwas Ähnliches in Shell zu tun. 

# Print (optional) error message and exit
# Usage: die [[msg] exit_status]
die() {
    [[ -n "$1" ]] && echo "$1"
    [[ -n "$2" ]] && exit $2 || exit 1
}

[[ -n "$tag" ]] || die "Need a tag argument.  Use $0 --help for details"

Dies setzt bash oder Korn Shell voraus, kann jedoch in eine klassische Bourne Shell konvertiert werden, indem [[]] in [] geändert wird.

1
Dan Christian

Der folgende Test stellt sicher, dass eine Variable entweder Null ist oder einen Wert zugewiesen hat. Die Anführungszeichen sind sehr wichtig und müssen verwendet werden!

VAL= # Creates a NULL variable
if [[ -z "$VAL" && "$VAL" = ’’ ]]
then
echo "The VAL variable is NULL"
fi
or
VAL=25
if [[ ! -z "$VAL" && "$VAL" != ’’ ]]
then
echo "The VAL variable is NOT NULL"
fi
0

Verwenden Sie den Mustervergleich, um festzustellen, ob der Wert nur aus Leerzeichen besteht:

pattern=$'*( |\t)'
if [[ $1 = $pattern ]]; then
    echo "First parameter has no non-whitespace characters"
    exit 1
fi

Das $'...'-Anführungszeichen erleichtert das Hinzufügen einer Registerkarte zur Zeichenfolge. Das erweiterte Muster *(...) stimmt mit 0 oder mehr mit den Mustern in den Klammern überein (ähnlich wie regulärer Ausdruck ( |\t)*). Das Muster wird einer Variablen zugewiesen, da = einen exakten Zeichenkettenabgleich durchführt, wenn ein Teil des Operanden für die rechte Hand in Anführungszeichen gesetzt wird. Wir führen also die Anführungszeichen vorher aus, um das Festlegen des Werts zu erleichtern.

0
chepner