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).

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.ä.


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}"

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).


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.


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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.