Eseguiamo lo script script1
dallo script script_main
script_main
:
#!/bin/bash
/tmp/script1
echo $?
sleep 2
echo script ended
script1
:
#!/bin/bash
exit 1
Come è ovvio, script1
esce con il codice di uscita 1
ma lo script principale continuerà fino alla fine.
La mia domanda:è possibile quando script1
exit 1
, quindi anche il main_script
verrà interrotto immediatamente?
Risposta accettata:
Il modo più semplice sarebbe avere esplicitamente il primo script exit
se l'altro script non è riuscito. Metti l'esecuzione dello script in un condizionale, come
otherscript.sh || exit 1
o
if ! otherscript.sh ; then
ret=$?
echo "otherscript failed with exit code $ret. exit." >&2
exit 1
fi
Ciò consentirebbe allo script principale di eseguire la pulizia che desidera, o semplicemente di provare qualche altra soluzione, possibilmente a seconda del codice di uscita del bambino. Nel primo, potremmo usare solo || exit
, per trasmettere il codice di uscita del bambino.
Se vuoi che lo script principale esca quando qualsiasi comando che si avvia non riesce, quindi set -e
.
set -e
otherscript.sh
echo "this will not run if otherscript fails"
set -e
non si applica ai programmi che vengono eseguiti all'interno di costrutti condizionali, quindi possiamo ancora testare codici particolari o accodarli con || true
ignorare il fallimento. Ma con punti di uscita ovunque ora, potremmo usare trap somecmd EXIT
per eseguire qualsiasi pulizia prima che la shell esca, indipendentemente da dove avvenga.
È anche possibile avere lo script interno forzare l'uscita dello script principale, ma un po 'ostile, non ti aspetteresti che una normale applicazione lo faccia. Ma, se lo desideri, il solo modo in cui lo script interno riprende il suo processo genitore è un modo:
$ cat mainscript.sh
#!/bin/bash
./otherscript.sh
echo "$0 exiting normally"
$ cat otherscript.sh
#!/bin/bash
echo "$0 kill $PPID"
kill $PPID
$ bash mainscript.sh
./otherscript.sh kill 11825
Terminated
Qui, se esegui otherscript.sh
da una shell interattiva, proverà a riprendere la sessione interattiva. Tutte le shell che ho testato sembrano ignorare il SIGTERM
in questo caso, tuttavia, quando si esegue in modo interattivo. In ogni caso, la shell principale potrebbe nuovamente trap
il SIGTERM
.
Invece di sparare solo al processo genitore, potresti usare kill 0
per terminare tutti i processi nel gruppo di processi otherscript.sh
viene eseguito. Se avviato da una shell non interattiva, di solito includerebbe il genitore.