set -u usage nefunguje podle očekávání

Učím se, jak efektivně používat různé set možnosti v mém skriptu a narazil na set -u, který se zdá být perfektní pro ukončení mého skriptu, pokud proměnná není správně nastavena (např. mazání uživatelů). Podle man stránky set -u a set -e provádí následující …

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

Vytvořil jsem testovací skript k otestování této funkce, ale nezdá se, že by fungoval podle očekávání . Možná by mi někdo mohl lépe vysvětlit můj problém a kde interpretuji špatně? Testovací skript je níže. Děkuji.

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

Očekávám, že skript zobrazí 0 a „Toto funguje“ a poté selže, protože ${testing2} je nenastaveno.

Místo toho se mi zobrazují 0 a „This works“ , následujte 0 a poté 0 Nemělo by se to objevit

Může někdo poskytnout nějaké znalosti? Děkuji.

Komentáře

  • Takže následná kontrola … existuje nějaký způsob, jak nastavit proměnnou na nulový řetězec nelegálně / vyvolat chybu? ' hádám, že ne.

Odpovědět

Od “ man Bash „:

Parametr je nastaven, pokud mu byla přiřazena hodnota. Null řetězec je platná hodnota. Jakmile je proměnná nastavena, lze ji zrušit pouze pomocí příkazu unset builtin.

Když to uděláte testing2= nastavujete proměnnou na nulový řetězec.

Změňte to na unset testing2 a zkuste to znovu.


The set -e v tomto případě nepomůže, protože přiřazení nikdy nemá ukončovací kód 1. Zkuste to, abyste viděli, že poslední provedený příkaz (přiřazení) má ukončovací kód 0, nebo přečtěte si tuto otázku :

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

A také věřím, že použití set -e je více problém, který je řešením.

Při použití nenastavených proměnných může dojít k chybě je set -u:

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

Bude výstup:

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

Odpověď

testing2= nastaví proměnnou testing2 na prázdný řetězec; proměnná je skutečně nastavena .

Pokud byste však měli spustit echo $testing99 v interaktivním prostředí Bash (bez nastavení errexit, tj. set -e), zobrazí se chyba:

bash: testing99: unbound variable 

Kromě

Při testování skriptů právě teď jsem zjistil, že interaktivní shell ne vždy ukončí při pokusu o rozbalení proměnné, která nebyla nastavena , zatímco neinteraktivní prostředí (spuštění skriptu prostředí) vždy ukončí . Podle manuálové stránky POSIX pro set:

-u Shell napíše zprávu na standardní chybu když se pokusí rozbalit proměnnou, která není nastavena, a okamžitě ukončit. Interaktivní prostředí se neukončí.

Interaktivní prostředí Bash se neukončí, pokud errexit nemá také bylo nastaveno. Na druhou stranu se interaktivní pomlčka nezavře – i když již byl set -e spuštěn.

Komentáře

  • Pokud pomlčka neopustí se set -e; set -u; zrušit aa; echo $ aa, pak pomlčka je špatná.
  • @schily Když jsem si to poprvé všiml, napadlo mě, že autoři pomlček věděli lépe než já a že ve specifikacích POSIXu mohla být nějaká nejednoznačnost, ale mít znovu zaškrtnuto pubs.opengroup.org/onlinepubs/9699919799/utilities/… , souhlasím, že to vypadá jako chyba, v pořádku.
  • Existuje jednoduché pravidlo: když se Korn Shell i Bourne Shell shodnou a jiná implementace prostředí má odchylku, pak se druhý shell chová nesprávně.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *