Detaily fungování shellu
Pořadí expanzí
Zadaný příkaz je po odeslání (stisknutí enteru) prohnán sérií expanzí:
- Expanze závorek (brace expansion)
a{d,c,b}e$\rightarrow$ade ace abe - Nahrazení vlnovky (tilde expansion)
Nahradí se~se obsah proměnné$HOME - Nahrazení proměnných (parameter and variable expansion)
Nahradí se výskyty$a,${b}apod za obsah proměnných (případně za prázdný string) - Vyhodnocení subshellů (command substitution)
`echo abc | tr a x`(nebo$(echo abc | tr a x)) $\rightarrowxbc - Aritmetická expanze (arithmetic expansion)
$(( 10 - 2*2))$\rightarrow$6 - Rozdělení na slova (word splitting)
Podle obsahu proměnné$IFS - Expanze wildcardů na názvy souborů (filename expansion)
Expandují se*,?a[]na názvy souborů (pokud žádný matchující soubor, zůstanou wildcardy)
Aritmetická expanze – proměnné
Při uvedení proměnné s dolarem se proměnná nahradí za svoji hodnotu během variable expansion, neexistující proměnná se nahradí za prázdný string:
x=$((10+$a))
# Aritmetická expanze dostane tento výraz:
x=$((10+))
# Což skončí syntaktickou chybu
Při uvedení proměnné bez dolaru neudělá variable expansion nic.
Proměnná se nahradí až během aritmetické expanze a neexistující proměnná se nahradí za hodnotu 0.
x=$((10+a))
# Správně přiřadí do x hodnotu 10
Rozdíl mezi $* a $@
$*při použití uvozovek spojí všechny argumenty do jednoho (tedy nejprve spojí jednou mezerou, pak teprve obaluje)$@při použití uvozovek předá každý argument samostatně (tedy nejprve obalí do uvozovek, pak teprve spojí jednou mezerou)
#!/bin/sh
for a in "$*"; do echo $a; done
echo "========"
for a in "$@"; do echo $a; done
Zavoláme ho takto:
./skript.sh "1 2" "3 4" "5 6"
Výstupem bude:
1 2 3 4 5 6
# Protože se proměnná "$*" expandovala na "1 2 3 4 5 6"
========
1 2
3 4
5 6
# Protože se proměnná "$@" expandovala na "1 2" "3 4" "5 6"