Lutilizzo di set -u non funziona come previsto

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.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *