GNU/Linux >> Znalost Linux >  >> Linux

Citace v rámci $(příkazová substituce) v Bash?

V mém prostředí Bash používám proměnné obsahující mezery a tyto proměnné používám v rámci substituce příkazů.

Jaký je správný způsob citování mých proměnných? A jak to mám udělat, pokud jsou vnořené?

DIRNAME=$(dirname "$FILE")

nebo cituji mimo substituci?

DIRNAME="$(dirname $FILE)"

nebo obojí?

DIRNAME="$(dirname "$FILE")"

nebo mám použít back-ticks?

DIRNAME=`dirname "$FILE"`

Jaký je správný způsob, jak to udělat? A jak mohu snadno zkontrolovat, zda jsou uvozovky nastaveny správně?

Přijatá odpověď:

V pořadí od nejhoršího k nejlepšímu:

  • DIRNAME="$(dirname $FILE)" nebude dělat to, co chcete, pokud $FILE obsahuje mezery (nebo jakékoli jiné znaky $IFS aktuálně obsahuje) nebo globbing znaky [?* .
  • DIRNAME=`dirname "$FILE"` je technicky správná, ale zpětná zaškrtnutí se pro rozšiřování příkazů nedoporučují kvůli mimořádné složitosti při jejich vnořování a zvláštnímu zpracování zpětných lomítek, ke kterému v nich dochází.
  • DIRNAME=$(dirname "$FILE") je správné, ale pouze proto, že se jedná o přiřazení ke skalární (nikoli maticové) proměnné. Pokud použijete substituci příkazu v jakémkoli jiném kontextu, například export DIRNAME=$(dirname "$FILE") nebo du $(dirname -- "$FILE") , nedostatek uvozovek způsobí potíže, pokud výsledek rozšíření bude obsahovat mezery nebo kulovité znaky.
  • DIRNAME="$(dirname "$FILE")" (kromě chybějícího -- , viz níže) je doporučený způsob. DIRNAME= můžete nahradit s příkazem a mezerou beze změny čehokoli jiného a dirname přijme správný řetězec.

Chcete-li se ještě zlepšit:

  • DIRNAME="$(dirname -- "$FILE")" funguje, pokud $FILE začíná pomlčkou.
  • DIRNAME="$(dirname -- "$FILE" && printf x)" && DIRNAME="${DIRNAME%?x}" || exit funguje, i když $FILE 's dirname končí novým řádkem, protože $() odřízne nové řádky na konci výstupu, oba ten přidaný dirname a ty, které mohou být součástí skutečných dat.

Rozšíření příkazů můžete vnořovat, jak chcete. Pomocí $() vždy vytvoříte nový kontext citací, takže můžete dělat věci jako toto:

foo "$(bar "$(baz "$(ban "bla")")")"

Vy ne chcete to zkusit pomocí zpětných znamének.


Linux
  1. spouštění apachectl z bash

  2. příkaz pro export bash

  3. Spusťte příkaz bash na jenkins pipeline

  1. Příkaz „eval“ v Bash?

  2. Syntaxe deklarace substituce příkazů v Bash – která z těchto dvou je lepší praxe?

  3. Náhrada příkazů pomocí „?

  1. Vysvětlení příkazu Bash trap

  2. bash sh - příkaz nenalezen

  3. Výstupní kód přiřazení proměnné k substituci příkazu v Bash