Detaily fungování shellu

Pořadí expanzí

Zadaný příkaz je po odeslání (stisknutí enteru) prohnán sérií expanzí:

  1. Expanze závorek (brace expansion)
    a{d,c,b}e $\rightarrow$ ade ace abe
  2. Nahrazení vlnovky (tilde expansion)
    Nahradí se ~ se obsah proměnné $HOME
  3. 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)
  4. Vyhodnocení subshellů (command substitution)
    `echo abc | tr a x` (nebo $(echo abc | tr a x)) $\rightarrow xbc
  5. Aritmetická expanze (arithmetic expansion)
    $(( 10 - 2*2)) $\rightarrow$ 6
  6. Rozdělení na slova (word splitting)
    Podle obsahu proměnné $IFS
  7. 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 $@

Vezměme si následující skript:

#!/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"