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ě.