GNU/Linux >> Znalost Linux >  >> Linux

Musím při přiřazování jejich výstupu k proměnné citovat substituce příkazů?

Tato otázka zde již má odpověď :Kdy je nutné dvojité uvozování?

(1 odpověď)
Uzavřeno před 4 lety.

Mám tendenci citovat substituce příkazů, jak je uvedeno níže, i když jejich výstup přiřazuji proměnné:

var="$(command)"

Je to ale vlastně potřeba? Kdy se to zlomí? Zde přijatá odpověď tvrdí:

DIRNAME=”$(dirname $FILE)” nebude dělat to, co chcete, pokud $FILE obsahuje mezery nebo kulové znaky [?*.

Odkaz ukazuje na skvělou stránku Grey Cat Wiki o citování, ale tato stránka nezmiňuje konkrétně citování substitucí příkazů. A při citování proměnné je zjevně potřeba, citace samotné substituce příkazu se nezdá být.

Stejný příspěvek však končí:

DIRNAME=”$(dirname “$FILE”)” je doporučený způsob. Můžete nahradit DIRNAME=příkazem a mezerou, aniž byste cokoli jiného změnili, a dirname obdrží správný řetězec.

Což jsem si také vždy myslel a často jsem zde opravoval příspěvky, které to necitovaly. Stránka wiki, na kterou odkazuje výše, však také tvrdí, že:

Existuje několik případů, kdy mohou být dvojité uvozovky bezpečně vynechány:

Na pravé straně jednoduchého zadání. Můžete napsat foo=$bar bez uvozovek. Toto je kompatibilní s POSIX.

[. . . ]

Zatímco var=$(command) není opravdu „jednoduché“ zadání, přesto jsem nebyl schopen najít případ, kdy byly uvozovky skutečně nutné:

$ var=$(echo "foo bar baz")  ## whitespace works
$  echo "$var"
foo bar baz

$ var=$(printf "foonbar * baz") ## so do globbing characters
$ echo "$var"
foo
bar * baz

$ var1="foonbar * baz"
$ var=$(printf "$var1")  ## printing a variable doesn't make any difference
$ echo "$var" 
foo
bar * baz

$ var=$(printf '%sn' "$var1")
$ echo "$var"
foonbar * baz

$ var=$(printf -- '-e %sn' "$var1") ## strings starting with - also work
$ echo "$var"
-e foonbar * baz

Uvozovky jsou samozřejmě naprosto nezbytné, pokud se substituce příkazu používá přímo pro věci jako command1 "$(command2)" , ale nezdá se, že by tomu tak bylo při přiřazování k proměnné.

Takže, co mi chybí? Jsou uvozovky někdy potřeba? Jaká velká a malá písmena budou citovat substituci příkazu při přiřazení návratové hodnoty proměnné chránit tě před? Nebo je vždy v pořádku neuvádět substituci příkazu, pokud se jedná o pravou stranu operace přiřazení proměnné?

Přijatá odpověď:

Jako jeden odkaz je v Bashově příručce toto jasné:

Proměnná může být přiřazena příkazem ve tvaru

name=[value]

Pokud hodnota není zadána, je proměnné přiřazen řetězec null. Všechny hodnoty procházejí rozšiřováním vlnovky, rozšiřováním parametrů a proměnných, substitucí příkazů, aritmetickým rozšiřováním a odstraňováním uvozovek (podrobnosti níže). […] Rozdělení slov se neprovádí , s výjimkou „[email protected]“, jak je vysvětleno níže. Rozšíření názvu souboru se neprovádí.

Žádné dělení slov, žádné rozšiřování názvu souboru, proto nejsou potřeba uvozovky.

Související:Nástroj příkazového řádku PostgreSQL psql a SET CONSTRAINTS ODLOŽENÉ?

Pokud jde o POSIX, sekce 2.9.1 Jednoduché příkazy:

2. Slova, která nejsou přiřazení proměnných nebo přesměrování, budou rozšířena. Pokud některá pole zůstanou po svém rozšíření Pokud některá pole zůstanou po svém rozšíření, první pole bude považováno za název příkazu a zbývající pole jsou argumenty příkazu.
[…]
4. Přiřazení každé proměnné se před přiřazením hodnoty rozšíří pro expanzi vlnovky, parametru, substituci příkazů, aritmetické rozšíření a odstranění kotace.

Nejsem si jistý, jestli to má být interpretováno tak, že k rozdělení pole dojde pouze u expanzí provedených v kroku 2? Krok 4 ne zmiňte rozdělení polí, i když část o rozdělení polí také nezmiňuje přiřazení proměnných jako výjimku z vytváření více polí.


Linux
  1. Jak nastavit proměnnou rovnou výstupu z příkazu v Grub2?

  2. Jak skrýt výstup terminálu při provádění příkazu?

  3. Zobrazení úplného výstupu příkazu PS

  1. příkaz openssl se zablokuje

  2. Číslo zařízení ve výstupu stat příkazu

  3. Přesměrování výstupu příkazu do proměnné v bash se nezdaří

  1. Příklady příkazů času Linux

  2. Převeďte výstup na řetězec

  3. Jak zachovat konce řádků při ukládání výstupu příkazu do proměnné?