Evitare di eseguire lo script se non viene definita una variabile


18

Ho una sceneggiatura simile a:

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

Tuttavia, l'utente deve fornire una chiamata variabile BATCHNUM e altrimenti devo forzare l'esecuzione di questo script. Sarebbe meglio se potessi forzare l'arresto dello script che chiama questo script (o anche lo script n. 1 che chiama lo script n. 2 che chiama questo script).

Risposte:


28

Il modo più rapido è probabilmente quello di aggiungere queste due righe all'inizio dello script:

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

La prima riga imposta l' nounsetopzione nella shell che esegue lo script, che si interrompe se si tenta di espandere una variabile non impostata; il secondo si espande $BATCHNUMnel contesto di una no-op, per innescare l'interruzione prima di fare qualsiasi altra cosa.

Se desideri un messaggio di errore più utile, puoi invece scrivere:

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

O simili.


18

Qui si desidera verificare che BATCHNUMsia impostato e non nullo.

La shell POSIX fornisce un'espansione dei parametri per questo lavoro. Basta aggiungere questa riga prima di utilizzare BATCHNUM:

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

o meglio per impostare il valore predefinito BATCHNUMse l'utente non ne ha fornito uno:

: "${BATCHNUM:=3}"

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

Questo funzionerà su bash e in un POSIX sh. Preferisco non distinguere tra variabili vuote e variabili non definite (cioè, non mi piace set -u, ma sono solo io).


2

Le linee

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

controlla vuoto $BATCHNUM. Con $PPIDte puoi fare tutto il male che vuoi al tuo genitore ( kill $PPID). Per aver ucciso tuo nonno, devi ottenere l'ID del processo con altri mezzi, come guardare i dati /proc/$PPID.

Tuttavia, se il tuo genitore muore, ti invia un segnale ( SIGHUP), quindi devi intrappolarlo prima di iniziare a uccidere qualcuno:

trap '' SIGHUP

Aggiornamento: se pensi di dover uccidere i tuoi genitori, stai sbagliando. Restituisce semplicemente un codice di uscita significativo. Lo script padre dovrebbe controllare il codice di ritorno dello script chiamato e reagire di conseguenza.


1
un po 'brutale .... :)
user40780

1

Per verificare se BATCHNUMè definito e uscire se non lo è:

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

Se si desidera anche rifiutare il caso in cui BATCHNUMè vuoto, utilizzare ${BATCHNUM:+a}invece di ${BATCHNUM+a}. Per informazioni sul ${VARIABLE+TEXT_IF_NULL}costrutto di espansione dei parametri, vedere ad esempio il manuale di bash .

Non uccidere il processo genitore. Non sai quale sia il processo genitore. Se alcuni script che lo chiamano devono interrompere se questo script si interrompe, verificare lo stato di uscita di questo script. Ad esempio nello script n. 2:

script3 || exit $?

oppure utilizzare set -eper interrompere lo script se un comando restituisce uno stato di errore (diverso da zero).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.