set -u gebruik werkt niet zoals verwacht

Ik leer hoe ik verschillende set opties in mijn script efficiënt kan gebruiken en kwam set -u tegen die perfect lijkt te zijn om mijn script af te sluiten als een variabele niet correct wordt ingesteld (bijv. gebruikers verwijderen). Volgens de man pagina, set -u en set -e doet het volgende …

-e Exit immediately if a command exits with a non-zero status. -u Treat unset variables as an error when substituting. 

Ik heb een testscript gemaakt om deze functionaliteit te testen, maar het lijkt niet te werken zoals verwacht . Misschien kan iemand mijn probleem beter aan mij uitleggen en waar ik verkeerd interpreteer? Testscript staat hieronder. Bedankt.

set -e set -u testing="This works" echo $? echo ${testing} testing2= echo $? echo ${testing2} testing3="This should not appear" echo $? echo ${testing3} 

Ik verwacht dat het script 0 en “Dit werkt” , en mislukt dan omdat ${testing2} is niet ingesteld.

In plaats daarvan word ik weergegeven 0 en “Dit werkt” , gevolgd door 0 en vervolgens 0 Dit mag niet verschijnen

Kan iemand enige kennis verstrekken? Bedankt.

Reacties

  • Dus follow-up … is er een manier om het instellen van een variabele in de null-string illegaal te maken / een foutmelding te geven? Ik ' vermoed van niet.

Antwoord

Van ” man Bash “:

Een parameter wordt ingesteld als er een waarde aan is toegewezen. De null-reeks is een geldige waarde. Als een variabele eenmaal is ingesteld, kan deze alleen worden uitgeschakeld door het ingebouwde unset-commando te gebruiken.

Wanneer u testing2= u stelt de variabele in op de null-string.

Verander dat in unset testing2 en probeer het opnieuw.


De set -e helpt in dit geval niet, aangezien een toewijzing nooit een exitcode van 1 heeft. Probeer dit om te zien dat het laatst uitgevoerde commando (de toewijzing) een exitcode van 0 heeft, of lees deze vraag :

$ false; a=""; echo $? 0 

En ik geloof ook dat het gebruik van set -e is meer een probleem dan een oplossing.

Wat een fout kan krijgen bij het gebruik van niet-ingestelde variabelen is set -u:

#!/bin/bash set -u testing="This works" echo ${testing} unset testing2 echo ${testing2} testing3="This should not appear" echo ${testing3} 

Zal het volgende weergeven:

$ ./script.sh This works ./script.sh: line 9: testing2: unbound variable 

Antwoord

testing2= stelt de testing2 variabele in op een lege string; de variabele is feitelijk is ingesteld .

Als u echter echo $testing99 in een interactieve Bash-shell zou draaien (zonder errexit, dwz set -e), zou u een foutmelding krijgen:

bash: testing99: unbound variable 

Afgezien van

Tijdens het testen van scripts zojuist, ontdekte ik dat een interactieve shell bij een poging om een variabele uit te breiden die niet is ingesteld terwijl een niet-interactieve shell (met een shellscript) sluit altijd af. Volgens de POSIX-manpagina voor set:

-u De shell zal een bericht schrijven naar standaardfout wanneer het een variabele probeert uit te breiden die niet is ingesteld en onmiddellijk wordt afgesloten. Een interactieve shell zal niet afsluiten.

Een interactieve Bash-shell zal niet afsluiten tenzij errexit ook is ingesteld. Aan de andere kant zal een interactieve dash-shell niet afsluiten – zelfs niet als set -e eerder is uitgevoerd.

Opmerkingen

  • Als het streepje niet wordt afgesloten met set -e; set -u; uitgeschakeld aa; echo $ aa, dan is streepje verkeerd.
  • @schily Toen ik dit voor het eerst opmerkte, dacht ik dat de auteurs van het streepje het beter wisten dan ik en dat er misschien wat onduidelijkheid was in de POSIX-specificaties, maar dat ik opnieuw gecontroleerd pubs.opengroup.org/onlinepubs/9699919799/utilities/… , ik ben het ermee eens dat het op een bug lijkt, oke.
  • Er is een simpele regel: wanneer zowel Korn Shell als Bourne Shell het eens zijn en een andere shell-implementatie een afwijking vertoont, gedraagt de andere shell zich niet correct.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *