GNU/Linux >> Znalost Linux >  >> Linux

Rozdíl mezi uvozovkami „…“, „…“, $“…“ a $“…“ ve skořápce?

Někdy vidím, že skripty shellu používají všechny tyto různé způsoby citování nějakého textu:"..." , '...' , $'...' a $"..." . Proč se používá tolik různých druhů citací?

Chovají se jinak nebo ovlivňují to, co v nich mohu dělat?

Přijatá odpověď:

Všechny znamenají něco jiného a můžete do nich napsat různé věci (nebo stejné věci s různým významem). Různé druhy citátů interpretují různé sekvence escape uvnitř nich (something ), nebo povolit nebo nepovolit proměnné interpolace ($something ) a další druhy expanze uvnitř nich.

Zkrátka:

  • '...' je zcela doslovné.
  • "..." umožňuje jak proměnné, tak vložené znaky uvozovek.
  • $'...' provádí znaky escape jako n , ale nerozšiřuje proměnné.
  • $"..." je pro překlady do lidského jazyka v Bash a ksh.

„Jednoduché uvozovky“

Cokoli napíšete mezi uvozovky, je zpracováno doslovně a není zpracováno vůbec. Zpětná lomítka a znaky dolaru tam nemají žádný zvláštní význam. To znamená, že u znaku (včetně jiných jednoduchých uvozovek!) nemůžete použít zpětné lomítko, interpolovat proměnnou nebo použít jakoukoli jinou funkci shellu.

Všechny tyto příklady vedou doslova k tomu, co je napsáno mezi uvozovkami:

Kód Výsledek
'hello world' ahoj světe
'/pkg/bin:$PATH' /balení/přihrádka:$PATH
'hellonworld' hellonworld
'`echo abc`' `echo abc`
'I'dn't've' Nepoznal jsem

Poslední je komplikovaný – jsou dva Řetězce v jednoduchých uvozovkách běží společně s nějakým textem bez uvozovek. První obsahuje I . Text v uvozovkách dn't obsahuje jednu uvozovku, která je uvozena na úrovni shellu , takže nezačíná řetězec v uvozovkách a je zahrnut jako doslovný znak (takže dn't ). Poslední řetězec v uvozovkách je jen ve . Všechny se spojí do jediného slova obvyklým způsobem, jak shell funguje.

Poněkud běžným idiomem pro kombinování doslovného textu a proměnných je jejich spouštění takto:

'let x="'$PATH"

výsledkem bude

let x="/usr/bin:/bin"

jako jedno slovo (lépe je $PATH uvozovat dvakrát také pro každý případ – mezery nebo kulové znaky v proměnné value mohou být zpracovány jinak – ale kvůli čitelnému příkladu běhu jsem to neudělal).

"Dvojité uvozovky"

Uvnitř dvojitých uvozovek jsou zpracovány dva druhy rozšíření a můžete použít zpětné lomítko k escapování znaků, abyste zabránili zpracování rozšíření nebo úniků.

Existují dvě kategorie rozšíření, ke kterým dochází uvnitř dvojitých uvozovek:

  • Ty začínající $ (rozšíření parametru $abc a ${abc} , substituce příkazu $(...) a aritmetické rozšíření $((...)) );
  • Náhrada příkazů zpětnými uvozovkami `abc`;

Uvnitř uvozovek může zpětné lomítko zabránit těmto rozšířením tím, že je vložíte před $ nebo ` . Může také ukončit dvojitou uvozovku, takže " obsahuje pouze " ve vašem řetězci nebo jiné zpětné lomítko. Jakékoli jiné zpětné lomítko je zachováno doslova – neexistují žádné úniky pro vytvoření dalších znaků a není odstraněno.

Některé z těchto příkladů fungují jinak než dříve a některé ne:

Kód Výsledek
"hello world" ahoj světe
"/pkg/bin:$PATH" /pkg/bin:/bin:/usr/bin
"hellonworld" hellonworld
"hello\nworld" hellonworld
"`echo abc`" abc
"I'dn't've" Neudělal(a)
"I'dn't've" Neudělal(a)
"I"dn"t've" Nevím
Související:Dhcpv6 – stavový VS bezstavový, jaký je mezi tím rozdíl?

Citace $'ANSI-C'

Tento druh uvozovek umožňuje zpracovat únikové cesty zpětného lomítka ve stylu C, ale ne vložené proměnné nebo substituce. Je to jediné druh citace, který podporuje úniky znaků .

Toto je rozšíření z ksh, které je nyní podporováno také v Bash, zsh a některých dalších shellech. Zatím není součástí standardu POSIX, takže jej maximálně přenosné skripty nemohou používat, ale skripty Bash nebo ksh jsou zdarma.

Všechny tyto escape mohou být použity s jejich C významy:a , b , f , n , r , t , v a doslovný escapování \ , ' , " a ? . Podporují také rozšíření e (escape znak) a v Bash a ksh cx (co by bylo zadáno pomocí Ctrl-x, např. cM je návrat vozíku). Skořápky mají řadu vlastních drobných rozšíření.

Umožňuje také čtyři druhy úniků obecných znaků:

  • nnn , jeden bajt s osmičkovou hodnotou nnn
  • xHH , jeden bajt s hexadecimální hodnotou HH
  • uHHHH , kódový bod Unicode, jehož hexadecimální index je HHHH
  • UHHHHHHHH , kódový bod Unicode, jehož hexadecimální index je HHHHHHHH

Všechny tyto číslice jsou po první číslici volitelné.

$ a ` nemají žádný význam a jsou zachovány doslovně, takže tam nemůžete zahrnout proměnnou.

Kód Výsledek
$'hello world' ahoj světe
$'/pkg/bin:$PATH' /balení/přihrádka:$PATH
$'hellonworld' ahoj
světe
$'`echo abc`' `echo abc`
$'I'dn't've' Neudělal(a)
$'U1f574u263A' 🕴☺

Většinu těchto úniků můžete simulovat pomocí printf příkaz, ačkoli POSIX vyžaduje pouze \ , a , b , f , n , r , t , v a nnn pracovat tam. K vložení printf můžete použít substituci příkazů v případě potřeby uvnitř dvojitých uvozovek:"Path:$(printf 't')$PATH" .

$”Locale translation”

Toto je rozšíření specifické pro ksh a Bash pro lokalizaci textových řetězců v přirozeném jazyce a vyhledává část v uvozovkách v katalogu zpráv. Nejprve provede všechna rozšíření dvojitých uvozovek. Pokud řetězec není v překladové databázi nalezen, použije se jako vlastní překlad. Vestavěný předpoklad je, že řetězce jsou v angličtině.

Pravděpodobně nebudete chtít použít tento, ale pokud ho uvidíte, můžete s ním obecně zacházet jako s běžnými dvojitými uvozovkami.

Jedna poznámka je, že neexistuje ne druh uvozovek, který umožňuje jak rozšíření vložených parametrů, tak vložené znaky escape. Ve většině případů, kdy byste to chtěli, by pro vás bylo lepší (bezpečnější) použití printf :

printf 'New path: e[1m%se[0m' "/pkg/bin:$PATH:"

To jasně odděluje, které části podléhají escapování znaků a které jsou datové hodnoty.

Další je, že všechny tyto styly citací vytvářejí v shellu jediné „slovo“, pokud [email protected] nebo rozšíření pole ${x[@]} se používá uvnitř dvojitých uvozovek. Obě formy v jednoduchých uvozovkách jsou vždy jedním slovem a nikdy se dále nerozšiřují.


Linux
  1. Rozdíl mezi vestavěným příkazem a příkazem, který není?

  2. Rozdíl mezi [[ $a ==Z* ]] a [ $a ==Z* ]?

  3. Rozdíl mezi Nss a Pam?

  1. Jaký je rozdíl mezi &> a >&v bash?

  2. Jaký je rozdíl mezi ls a l?

  3. Jaký je rozdíl mezi unlink a rm?

  1. Jaký je rozdíl mezi InnoDB a MyISAM?

  2. Přesný rozdíl mezi ‚terminálem‘, ‚shell‘, ‚tty‘ a ‚konzolí‘?

  3. Rozdíl mezi přihlašovacím prostředím a nepřihlašovacím prostředím?