Jako primárně Java programátor najdu bash if
–then
konstrukce je docela matoucí, zejména pokud jde o mezery. Může někdo vysvětlit, proč první funguje, ale ne druhý nebo třetí?
#works
if [ -n $1 ]; then echo "parameterized"; fi
#output: ./links: Zeile 1: [-n: Kommando nicht gefunden.
if [-n $1 ]; then echo "parameterized"; fi
#output: ./links: Zeile 1: [: Fehlende `]'
if [ -n $1]; then echo "parameterized"; fi
Přijatá odpověď:
Tato nekonzistence je z velké části způsobena historickými důvody.
Použití hranatých závorek jako podmíněného příkazu přišlo po použití hranatých závorek ve vzorech zástupných znaků. Takže v té době [ -n foo ]
přišel na scénu, [foo]
již znamenalo „soubor, jehož název je f
nebo o
“. Zatímco jen málo použití operátoru hranatých závorek v praxi by bylo v rozporu s realistickým použitím hranatých závorek v zástupných znacích, autoři se rozhodli neriskovat porušení stávajících skriptů změnou syntaxe. Tato volba designu také usnadnila implementaci:zpočátku [
byl implementován jako externí příkaz, který by nemohl být proveden, pokud byla mezera za [
byla volitelná. (Moderní systémy stále mají [
jako externí příkaz, ale téměř všechny moderní shelly jej mají také zabudovaný.)
Z podobných důvodů je váš „pracovní“ kód ve většině případů ve skutečnosti nesprávný. $1
neznamená „hodnotu parametru 1“:znamená „vezměte hodnotu parametru 1, rozdělte ji do samostatných slov na prázdné místo (nebo jakoukoli hodnotu IFS
je) a interpretovat každé slovo jako vzor glob“. Způsob zápisu „hodnoty parametru 1“ vyžaduje dvojité uvozovky:"$1"
. Viz Kdy je nutné dvojité uvozování? pro hloupé. Nemusíte tomu rozumět; vše, co si musíte zapamatovat, je:vždy umístěte dvojité uvozovky kolem substitucí proměnných "$foo"
a substituce příkazů "$(foo)"
. Tedy:
if [ -n "$1" ]; then …
V bash, ksh a zsh, ale ne v obyčejném sh, můžete také použít dvojité závorky. Jednoduché závorky [ … ]
jsou analyzovány jako běžný příkaz (a skutečně [
je obyčejný příkaz, i když obvykle zabudovaný). Dvojité závorky jsou samostatnou syntaktickou konstrukcí a dvojité uvozovky můžete většinou vynechat.
if [[ -n $1 ]]; then …
Existuje však výjimka:[[ "$foo" = "$bar" ]]
Chcete-li otestovat, zda mají tyto dvě proměnné stejnou hodnotu, vyžaduje se uvozovky kolem $bar
, jinak $bar
je interpretován jako zástupný vzor. Opět, místo abyste si pamatovali podrobnosti, můžete také neustále používat dvojité uvozovky.