(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í.