GNU/Linux >> Znalost Linux >  >> Linux

Jsou Bash testy tak náročné na mezery?

Jako primárně Java programátor najdu bash ifthen 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.

Související:Počínaje bash:argumenty -lt a -gt?
Linux
  1. Závorky ve stavu If:Proč dostávám chyby syntaxe bez mezer?

  2. Otestujte, zda řetězec nemá v Bash znaky bez mezer

  3. Názvy hostitelů – o čem jsou?

  1. Co potřebují správci systému vědět o používání Bash

  2. Rozdíl mezi proměnnými Shell, které se exportují, a těmi, které nejsou v Bash?

  3. Jaké funkce jsou v Zsh a chybí Bash, nebo naopak?

  1. Co jsou oddělovače slov Readline?

  2. Chybí struny po zřetězení dvou nebo více proměnných řetězců v bash?

  3. Jaké jsou speciální parametry/proměnné (bash) Shell?