Ho uno script bash che viene eseguito tre controlli oltre il mio codice sorgente, e quindi exit 0
se tutti i comandi sono riusciti, o exit 1
se qualcuno di loro non è riuscito:codici di uscita AND in bash
#!/bin/bash
test1 ./src/ --test-1=option
exit_1=$?
test2 ./src/ test-2-options
exit_2=$?
test3 ./src/ -t 3 -o options
exit_3=$?
# Exit with error if any of the above failed
[[ $exit_1 -eq 0 && $exit_2 -eq 0 && $exit_3 -eq 0 ]]
exit $?
Questo codice funziona, ma sembra troppo lungo e prolisso. C'è un modo in cui questo può essere reso più bello? In particolare non sono felice con:
- Dovendo eseguire il comando, e poi assegnare il codice di uscita a una variabile
- dover utilizzare
[[ ... ]]
, poi raccogliere il suo codice di uscita nella riga successiva a uscita con - Dovendo confrontare esplicitamente variabili da 0, come nel
[[ $var -eq 0 ]]
, invece di trattarli come booleani
Idealmente, il risultato finale wou ld essere qualcosa di più leggibile simile:
exit_1=(test1 ./src/ --test-1=option)
exit_2=(test2 ./src/ test-2-options)
exit_3=(test3 ./src/ -t 3 -o options)
# Exit with error if any of the above failed
exit ($exit_1 && $exit_2 && $exit_3)
Alcune cose che ho preso in considerazione:
Ottenere il codice di errore per una variabile in una riga:
exit_1=$(test1 ./src/ --test-1=option)$?
exit_2=$(test2 ./src/ test-2-options)$?
exit_3=$(test3 ./src/ -t 3 -o options)$?
questo funziona e lo rende un po 'più breve, ma non ho mai visto nessun altro utilizzarlo prima. È una cosa sensata/sensata da fare? Ci sono problemi con questo?
Basta eseguire i test, e & & insieme:
test1 ./src/ --test-1=option && \
test2 ./src/ test-2-options && \
test3 ./src/ -t 3 -o options
status=$?
Questo fa non lavoro, come cortocircuiti bash. Se test1
fallisce, test2 e test3 non vengono eseguiti e voglio che vengano eseguiti tutti.
Detecing errori ed uscendo con || exit
[[ $exit_1 -eq 0 && $exit_2 -eq 0 && $exit_3 -eq 0 ]] || exit 1
Questo consente di risparmiare una riga di codici di uscita scomode e variabili, ma il bit importante exit 1
è ora a destra alla fine della riga in cui si può mancarlo. Idealmente, qualcosa di simile a questo dovrebbe funzionare:
exit [[ $exit_1 -eq 0 && $exit_2 -eq 0 && $exit_3 -eq 0 ]]
Naturalmente, questo non non lavoro, come [[
restituisce la sua uscita, invece di eco esso.
exit $([[ $exit_1 -eq 0 && $exit_2 -eq 0 && $exit_3 -eq 0 ]] ; echo $?)
fa lavoro, ma sembra ancora come un cludge orribile
non esplicitamente trattare con uscita codici-as-booleani
[[ $exit_1 && $exit_2 && $exit_3 ]]
Questo non fa cosa speri che lo farebbe. Il modo più semplice di & & insieme tre codici di ritorno memorizzati nelle variabili è con il completo $var -eq 0 && ...
. Sicuramente c'è un modo più bello?
So bash non è un bel linguaggio di programmazione - se si può anche chiamare così - ma c'è un modo per rendere questo meno imbarazzante?
L'approccio 'var = $ (pippo) $?' È interessante, ma mette le chiamate di prova in una subshell non necessaria. – kojiro
Per lo meno, la tua finale 'exit $?' Non è necessaria se '[[... && ... && ...]]' è l'ultima affermazione dello script. – chepner