Unikaj uruchamiania skryptu, jeśli zmienna nie jest zdefiniowana


18

Mam skrypt wygląda następująco:

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

Jednak użytkownik musi podać zmienne wywołanie BATCHNUM, w przeciwnym razie muszę wymusić zatrzymanie działania tego skryptu. Byłoby lepiej, gdybym mógł zmusić skrypt, który wywołuje ten skrypt, do zatrzymania się (lub nawet skrypt nr 1, który wywołuje skrypt nr 2, który wywołuje ten skrypt).

Odpowiedzi:


30

Najszybszym sposobem jest prawdopodobnie dodanie tych dwóch wierszy na początku skryptu:

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

Pierwszy wiersz ustawia nounsetopcję w powłoce uruchamiającej skrypt, która przerywa się, jeśli spróbujesz rozwinąć nieokreśloną zmienną; drugi rozszerza się $BATCHNUMw kontekście braku operacji, aby wywołać przerwanie przed zrobieniem czegokolwiek innego.

Jeśli potrzebujesz bardziej pomocnego komunikatu o błędzie, możesz zamiast tego napisać:

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

Lub podobne.


18

Tutaj chcesz sprawdzić, czy BATCHNUMjest ustawiona, a nie zerowa.

Powłoka POSIX zapewnia rozszerzenie parametru dla tego zadania. Po prostu dodaj ten wiersz przed użyciem BATCHNUM:

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

lub lepiej ustawić wartość domyślną, BATCHNUMjeśli użytkownik jej nie podał:

: "${BATCHNUM:=3}"

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

Działa to w trybie bash i POSIX sh. Wolę nie rozróżniać pustych zmiennych od niezdefiniowanych zmiennych (tzn. Nie lubięset -u , ale to tylko ja).


2

Linie

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

sprawdź, czy jest pusty $BATCHNUM. Dzięki $PPIDniemu możesz wyrządzić rodzicowi krzywdę, jaką chcesz (kill $PPID ). Aby zamordować dziadka, musisz uzyskać identyfikator procesu w inny sposób, na przykład patrząc na dane /proc/$PPID.

Jeśli jednak twój rodzic umiera, wysyła ci sygnał ( SIGHUP), więc musisz go złapać, zanim zaczniesz zabijać kogokolwiek:

trap '' SIGHUP

Aktualizacja: Jeśli uważasz, że musisz zabić rodziców, robisz to źle. Po prostu zwróć znaczący kod wyjścia. Skrypt nadrzędny powinien sprawdzić kod powrotu wywoływanego skryptu i odpowiednio zareagować.


1
trochę brutalne .... :)
user40780

1

Aby sprawdzić, czy BATCHNUMjest zdefiniowane i wyjść, jeśli nie jest:

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

Jeśli chcesz również odrzucić skrzynkę, w której BATCHNUMjest pusta, użyj ${BATCHNUM:+a}zamiast ${BATCHNUM+a}. Aby uzyskać informacje na temat ${VARIABLE+TEXT_IF_NULL}konstrukcji rozszerzenia parametru, patrz np . Instrukcja bash .

Nie zabijaj procesu nadrzędnego. Nie wiesz, co to jest proces nadrzędny. Jeśli jakiś skrypt, który go wywołuje, musi przerwać działanie, jeśli ten skrypt zostanie przerwany, spraw, aby sprawdził status wyjścia tego skryptu. Np. W skrypcie nr 2:

script3 || exit $?

lub użyj, set -eaby przerwać skrypt, jeśli dowolne polecenie zwróci status błędu (niezerowy).

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.