Sto imparando a utilizzare in modo efficiente le diverse opzioni set
nel mio script e mi sono imbattuto in set -u
che sembra essere perfetto per uscire dal mio script se una variabile non viene impostata correttamente (es. eliminazione di utenti). Secondo la pagina man , set -u
e set -e
esegue le seguenti operazioni …
-e Exit immediately if a command exits with a non-zero status. -u Treat unset variables as an error when substituting.
Ho creato uno script di test per testare questa funzionalità, ma non sembra funzionare come previsto . Forse qualcuno potrebbe spiegarmi meglio il mio problema e dove sto interpretando male? Lo script di test è di seguito. Grazie.
set -e set -u testing="This works" echo $? echo ${testing} testing2= echo $? echo ${testing2} testing3="This should not appear" echo $? echo ${testing3}
Mi aspetto che lo script visualizzi 0 e “Funziona” , quindi fallisce come ${testing2}
non impostato.
Vengo invece visualizzato 0 e “Funziona” , seguito da 0 e poi da 0 Non dovrebbe apparire
Qualcuno può fornire alcune conoscenze? Grazie.
Commenti
- Quindi follow-up … cè un modo per rendere illegale limpostazione di una variabile sulla stringa nulla / generare un errore? ' suppongo di no.
Risposta
Da ” man Bash “:
Un parametro viene impostato se gli è stato assegnato un valore. La stringa nulla è un valore valido. Una volta che una variabile è stata impostata, può essere annullata solo utilizzando il comando integrato unset.
Quando si esegue testing2=
stai impostando la variabile sulla stringa nulla.
Cambialo in unset testing2
e riprova.
Il set -e
non aiuta in questo caso poiché unassegnazione non ha mai un codice di uscita 1. Prova questo per vedere che lultimo comando eseguito (lassegnazione) ha un codice di uscita 0, o leggi questa domanda :
$ false; a=""; echo $? 0
E credo anche che luso di set -e sia più un problema che una soluzione.
Ciò che può generare un errore con luso di variabili non impostate è set -u
:
#!/bin/bash set -u testing="This works" echo ${testing} unset testing2 echo ${testing2} testing3="This should not appear" echo ${testing3}
Produrrà:
$ ./script.sh This works ./script.sh: line 9: testing2: unbound variable
Risposta
testing2=
imposta la variabile testing2
su una stringa vuota; la variabile in realtà è impostata .
Tuttavia, se si dovesse eseguire echo $testing99
in una shell Bash interattiva (senza impostare errexit
, cioè set -e
), riceverai un errore:
bash: testing99: unbound variable
A parte
Mentre testavo gli script proprio ora, ho scoperto che una shell interattiva non esce sempre quando si tenta di espandere una variabile che non è stata impostata durante una shell non interattiva (che esegue uno script di shell) esce sempre da . Secondo la pagina man POSIX per set
:
-u La shell scriverà un messaggio per lo standard error quando tenta di espandere una variabile non impostata e esce immediatamente. Una shell interattiva non deve uscire.
Una shell Bash interattiva non terminerà a meno che errexit
non abbia anche stato impostato. Daltra parte, una dash shell interattiva non verrà chiusa, anche se set -e
è stato eseguito in precedenza.
Commenti
- Se il trattino non esce con set -e; set -u; unset aa; echo $ aa, quindi il trattino è sbagliato.
- @schily Quando lho notato per la prima volta, ho pensato che gli autori del trattino sapessero meglio di me e che potesse esserci stata qualche ambiguità nelle specifiche POSIX, ma verificato pubs.opengroup.org/onlinepubs/9699919799/utilities/… , sono daccordo che sembra un bug, bene.
- Esiste una regola semplice: quando sia Korn Shell che Bourne Shell sono daccordo e unaltra implementazione della shell ha una deviazione, laltra shell si comporta in modo errato.