Domanda

Sono un noob in guscio di script. Voglio stampare un messaggio e uscire il mio script, se un comando non riesce. Ho provato:

my_command && (echo 'my_command failed; exit)

, ma non funziona. Mantiene l'esecuzione delle istruzioni seguendo questa linea nello script. Sto utilizzando Ubuntu e bash.

È stato utile?

Soluzione

Prova:

my_command || { echo 'my_command failed' ; exit 1; }

quattro cambiamenti:

  • Cambia && a ||
  • Usa { } al posto di ( )
  • Introdurre ; dopo exit e
  • spazi dopo { e prima }

Dal momento che si desidera stampare il messaggio e uscire solo quando il comando non riesce (uscite con valore diverso da zero) è necessario un || non un &&.

cmd1 && cmd2

verrà eseguito cmd2 quando cmd1 riesce (uscita valore 0). Dove, come

cmd1 || cmd2

eseguirà cmd2 quando cmd1 fallisce (valore non zero).

Utilizzando ( ) rende il comando all'interno correre in un sub-shell e chiamare un exit da lì ti fa uscire dal sub-shell e non la shell originale, quindi l'esecuzione continua nella shell originale.

Per ovviare a questo uso { }

Le ultime due variazioni sono richiesti da bash.

Altri suggerimenti

Le altre risposte hanno coperto il diretto bene, ma si può anche essere interessati a utilizzare set -e. Con questo, qualsiasi comando che non riesce (al di fuori di contesti specifici come test if) farà sì che lo script di abortire. Per alcuni script, è molto utile.

Se si desidera che il comportamento per tutti i comandi nello script, basta aggiungere

  set -e 
  set -o pipefail

all'inizio dello script. Questa coppia di opzioni dire all'interprete bash per uscire ogni volta che un comando ritorna con un-diverso da zero codice di uscita.

Questo non consente di stampare un messaggio di uscita, però.

Si noti inoltre, stato d'uscita di ogni comando viene memorizzato nella variabile di shell $ ?, quale è possibile verificare subito dopo l'esecuzione del comando. Un non-zero di stato indica il fallimento:

my_command
if [ $? -eq 0 ]
then
    echo "it worked"
else
    echo "it failed"
fi

Ho messo il seguente linguaggio:

echo "Generating from IDL..."
idlj -fclient -td java/src echo.idl
if [ $? -ne 0 ]; then { echo "Failed, aborting." ; exit 1; } fi

echo "Compiling classes..."
javac *java
if [ $? -ne 0 ]; then { echo "Failed, aborting." ; exit 1; } fi

echo "Done."

precedere ciascun comando con un'eco informativo, e seguire ogni comando con lo stesso
 Linea if [ $? -ne 0 ];.... (Naturalmente, è possibile modificare il messaggio di errore se si desidera).

my_command fornite si canonicamente progettato, es restituisce 0 quando riesce, quindi && è esattamente il contrario di ciò che si vuole. Volete ||.

Si noti inoltre che ( non mi sembra giusto per me in bash, ma non riesco a provare da dove mi trovo. Dimmi.

my_command || {
    echo 'my_command failed' ;
    exit 1; 
}

È anche possibile utilizzare, se si desidera mantenere lo stato di errore di uscita, e hanno un file leggibile con un solo comando per riga:

my_command1 || exit $?
my_command2 || exit $?

Questo, tuttavia, non stamperà alcun messaggio di errore aggiuntivo. Ma in alcuni casi, l'errore verrà stampato dal comando fallito in ogni caso.

Il comando incorporato shell trap permette cattura segnali, e altre condizioni utili, tra l'esecuzione di comandi fallita (cioè, uno stato di ritorno diverso da zero). Quindi, se non si vuole esplicitamente test di stato di ritorno di ogni singolo comando si può dire trap "your shell code" ERR e il codice shell saranno eseguiti ogni volta che un comando restituisce uno status diverso da zero. Ad esempio:

trap "echo script failed; exit 1" ERR

Si noti che come in altri casi di cattura comandi falliti, oleodotti hanno bisogno di un trattamento speciale; Quanto sopra non prenderà false | true.

Le seguenti funzioni solo echi errori se un comando non riesce:

silently () {
    label="${1}"
    command="${2}"
    error=$(eval "${command}" 2>&1 >"/dev/null")

    if [ ${?} -ne 0 ]; then
        echo "${label}: ${error}" >&2
        exit 1
    fi
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top