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"