Vermeiden Sie es, das Skript auszuführen, wenn keine Variable definiert ist

15

Ich habe ein Skript sieht aus wie:

c=0
for f in */*; do
cp -v "$f" "/myhome/CE$(printf '%0*d' 2 $BATCHNUM)-new-stuctures_extracted/test-$(printf '%0*d' 5 $c)"
c=$((c=c+1))
done

Der Benutzer muss jedoch einen Variablenaufruf BATCHNUM bereitstellen, andernfalls muss ich erzwingen, dass dieses Skript nicht mehr ausgeführt wird. Es wäre besser, wenn ich das Skript, das dieses Skript aufruft, zum Beenden zwingen könnte (oder sogar das Skript Nr. 1, das das Skript Nr. 2 aufruft, das dieses Skript aufruft).

user40780
quelle

Antworten:

26

Am schnellsten geht es wahrscheinlich, wenn Sie diese beiden Zeilen am Anfang des Skripts einfügen:

set -u # or set -o nounset
: "$BATCHNUM"

In der ersten Zeile wird die nounsetOption in der Shell festgelegt, in der das Skript ausgeführt wird. Diese Option wird abgebrochen, wenn Sie versuchen, eine nicht festgelegte Variable zu erweitern. Die zweite Option wird $BATCHNUMim Kontext eines No-Ops erweitert, um den Abbruch auszulösen, bevor etwas anderes ausgeführt wird.

Wenn Sie eine hilfreichere Fehlermeldung wünschen, können Sie stattdessen Folgendes schreiben:

if [[ -z "$BATCHNUM" ]]; then
    echo "Must provide BATCHNUM in environment" 1>&2
    exit 1
fi

O.ä.

Tom Hunt
quelle
16

Hier möchten Sie überprüfen, BATCHNUMist gesetzt und nicht null.

POSIX-Shell bietet eine Parametererweiterung für diesen Job. Fügen Sie einfach diese Zeile hinzu, bevor Sie BATCHNUM:

: "${BATCHNUM:?Variable not set or empty}"

oder besser, um den Standardwert festzulegen, BATCHNUMfalls der Benutzer keinen angegeben hat:

: "${BATCHNUM:=3}"
cuonglm
quelle
3
[ -n "$BATCHNUM" ] || { kill "$PPID"; exit 1; }
#Unless $BATCHNUM is defined and unempty, ask parent process to exit and exit w/ 1

Dies funktioniert auf Bash und in einem POSIX-SH. Ich bevorzuge es, nicht zwischen leeren Variablen und undefinierten Variablen zu unterscheiden (dh ich mag es nicht set -u, aber das bin nur ich).

PSkocik
quelle
2

Die Linien

if [ -z "$BATCHNUM" ]; then
    exit 2;
fi

auf leer prüfen $BATCHNUM. Mit $PPIDkönnen Sie Ihren Eltern nach Belieben Schaden zufügen ( kill $PPID). Um Ihre Großeltern zu ermorden, müssen Sie die Prozess-ID auf andere Weise ermitteln, z. B. durch Betrachten der Daten in /proc/$PPID.

Wenn Ihr Elternteil jedoch stirbt, sendet es ein Signal ( SIGHUP) an Sie, sodass Sie es abfangen müssen, bevor Sie jemanden töten:

trap '' SIGHUP

Update: Wenn du denkst, dass du deine Eltern töten musst, machst du es falsch. Geben Sie einfach einen aussagekräftigen Exitcode zurück. Das übergeordnete Skript sollte den Rückkehrcode des aufgerufenen Skripts überprüfen und entsprechend reagieren.

Thomas Erker
quelle
1
ein bisschen brutal .... :)
user40780
1

So testen Sie, ob BATCHNUMdefiniert ist, und beenden Sie das Programm, wenn dies nicht der Fall ist:

if [ -n "${BATCHNUM-a}" ]; then
  echo >&2 "Fatal error: BATCHNUM not set"
  exit 2
fi

Wenn Sie auch den Fall ablehnen möchten, in dem BATCHNUMleer ist, verwenden Sie ${BATCHNUM:+a}anstelle von ${BATCHNUM+a}. Informationen zum ${VARIABLE+TEXT_IF_NULL}Parametererweiterungskonstrukt finden Sie z . bash-Handbuch .

Beenden Sie nicht den übergeordneten Prozess. Sie wissen nicht, was der übergeordnete Prozess ist. Wenn ein Skript, das dieses aufruft, abgebrochen werden muss, wenn dieses Skript abgebrochen wird, überprüfen Sie den Beendigungsstatus dieses Skripts. ZB in Skript Nr. 2:

script3 || exit $?

oder verwenden Sie set -e, um das Skript abzubrechen, wenn ein Befehl einen Fehlerstatus (ungleich Null) zurückgibt.

Gilles 'SO - hör auf böse zu sein'
quelle