Uvozování
Uvozování lze shellu říct, že určitou část řádku má brát doslova a neprovádět na ní některé expanze. Po provedení všech expanzí shell uvozovací znaky odstraní — to je poslední fáze, odstranění uvozovek. Odstraní se pouze ty uvozovky, které jsme napsali ve skriptu, nikoliv ty, které vznikly expanzí.
Uvozovacích prostředků je několik a liší se tím, co potlačí.
Zpětné lomítko
Zpětné lomítko potlačí zvláštní význam následujícího znaku.
> echo Cena je 100 $
Cena je 100 $
> echo Cena je 100 \$\{X\}
Cena je 100 ${X}
> touch muj\ soubor.txt
Zpětné lomítko na konci řádku ruší znak nového řádku, což umožňuje rozdělit dlouhý příkaz na více řádků.
grep -r 'vzor' \
--include='*.txt' \
/var/log
Apostrofy
Apostrofy potlačí všechny expanze i zvláštní význam všech znaků. Uvnitř apostrofů nelze zapsat apostrof — ani pomocí zpětného lomítka.
> echo '${HOME} a $(date) a *.txt'
${HOME} a $(date) a *.txt
Potřebujeme-li v takovém řetězci apostrof, musíme uvozování přerušit:
> echo 'nelze to'\''udelat jinak'
nelze to'udelat jinak
Uvozovky
Uvozovky potlačí expanzi závorek, vlnovky, dělení slov a expanzi jmen souborů, ale ponechají expanzi parametrů, aritmetickou expanzi a substituci příkazů. Právě proto je to nejčastěji používaná forma.
> echo "domov je ${HOME}, dnes je $(date +%A), soubory: *.txt"
domov je /home/petr, dnes je Wednesday, soubory: *.txt
Uvnitř uvozovek si zvláštní význam zachovávají znaky $, ` a \; ostatní
znaky, včetně * a mezery, jsou brány doslova. Zpětné lomítko uvnitř uvozovek
funguje pouze před těmito znaky a před uvozovkou:
> echo "cena je \${X}"
cena je ${X}
> echo "zpetne lomitko: \d"
zpetne lomitko: \d
Zápis $'…'
Zápis $'…' se chová jako apostrofy, ale navíc interpretuje sekvence se zpětným
lomítkem podobně jako v jazyce C.
| sekvence | znak |
|---|---|
\n | nový řádek |
\t | tabulátor |
\r | návrat vozíku |
\\ | zpětné lomítko |
\' | apostrof |
\nnn | znak s osmičkovým kódem nnn |
\xHH | znak se šestnáctkovým kódem HH |
\uHHHH | znak Unicode |
> echo $'prvni\ndruhy'
prvni
druhy
> IFS=$'\n'
Tuto konstrukci jsme použili v kapitole Cykly při
nastavování IFS; jde tedy o běžný zápis, nikoliv o kuriozitu. Expanze
proměnných uvnitř $'…' neprobíhá.
Shrnutí
| co potlačíme | \znak | '…' | "…" | $'…' |
|---|---|---|---|---|
| expanze závorek | ano | ano | ano | ano |
| expanze vlnovky | ano | ano | ano | ano |
| expanze parametrů | ano | ano | ne | ano |
| aritmetická expanze | ano | ano | ne | ano |
| substituce příkazů | ano | ano | ne | ano |
| dělení slov | ano | ano | ano | ano |
| expanze jmen souborů | ano | ano | ano | ano |
interpretace \n, \t | — | ne | ne | ano |
Praktické pravidlo pro psaní skriptů: expanze proměnných a příkazů píšeme v uvozovkách, pokud výslovně nechceme dělení slov nebo expanzi jmen souborů. Řetězce, ve kterých nemá nic expandovat, píšeme do apostrofů.
# spravne
cp "${zdroj}" "${cil}"
grep -r 'chybova hlaska' "${adresar}"
# spatne: rozpadne se na jmenech s mezerami
cp ${zdroj} ${cil}