17Kapitola

Bash 17: Práce s parametry/argumenty

Tentokrát se naučíme pracovat s parametry, které uživatel posílá skriptu z příkazové řádky. Navážeme tak na předchozí části, kdy jsme se seznámili s příkazy, které nám umožnily komunikovat s uživatelem během provádění skriptu.

Poziční parametry

Poziční parametry jsou něčím, co zná každý, kdo pracuje s příkazovou řádkou. Jsou to jednoduše všechny takové ty přepínače a parametry, které přidáváme za různé příkazy. Např. zadáním ls jsme nepředali žádný parametr. V případě ls /home je jediným parametrem /home. Při zadání ls /hoem /opt jsou dvěma parametry /home a /opt. Parametrem je ale také --help, pokud zadáme ls --help. Dvěma parametry u ls -l /home jsou pak -l a /home. V mnoha případech (např. u příkazů cp a mount) záleží na tom, v jakém pořadí se který parametr nachází, resp. na kolikáté pozici je. Z toho důvodu se těmto parametrům říká poziční parametry.

Bash před spuštěním příkazu od sebe oddělí jednotlivé parametry a naplní jimi zvláštní sadu proměnných. První zadaný poziční parametr tak spuštěný program (nebo skript) najde v proměnné $1, druhý v $2, třetí v $3 atd.

Uveďme malý příklad. V něm bude skript vypisovat hlášku "uživatel nechce pomoc", pokud nebude prvním parametrem -h. V případě, že jej uvedete, zobrazí se pomoc pro uživatele. Hodnotu prvního pozičního parametru čteme z proměnné $1:

#!/bin/bash
if [ "$1" = "-h" ]; then
echo "pomoc pro uživatele!"
else
echo "uživatel nechce pomoc!"
fi

Nyní si tento skript uložte, nastavte mu práva spouštění (viz 8. díl) a zkuste jej spustit bez parametru, s parametrem -h, příp. i s jinými parametry.

Trochu odlišné je volání desátého a vyšších pozičních parametrů. Pokud totiž zadáme echo $10, zobrazil by se obsah prvního pozičního parametru (tj. hodnota $1) a znak nula (0). Abychom získali desátý poziční parametr, musíme zadat echo ${10}.

 

Související proměnné

Zajímavým případem je $0. Uvádí jakoby nultý poziční parametr, tedy parametr předcházející tomu prvnímu. Na příkazovém řádku je ale před prvním parametrem napsán samotný příkaz. A právě přesné jméno (včetně případně zadané cesty) je náplní této proměnné. K čemu to je dobré? Program tak může snadno zjistit, jakým způsobem byl spuštěn a jak se vlastně jmenuje.

Protipólem nultého parametru jsou $* a $@. Oba zobrazí seznam všech pozičních parametrů. V prvním případě oddělených předdefinovatelným oddělovačem (problematiku interních proměnných probereme v některém z následujících dílů), ve druhém případě mezerou.

Pokud bychom tak chtěli zjistit, jak přesně byl spuštěn skript, dosáhli bychom toho příkazem echo $0 $@. Hodit se může také znalost celkového počtu pozičních parametrů. K tomu slouží speciální proměnná $#.

Příkazy shift

S pozičními parametry souvisí interní příkaz Bashe zvaný shift. Není to jen pojmenování přeřaďovače na klávesnici, ale především anglické slovo s významem posunout. A to je také podstatou tohoto příkazu. Posunuje poziční argumenty. Sám přitom přijímá jediný argument, kterým je číslo.

Jednoduše řečeno, když zadáme např. shift 2, budou vypuštěny první dva poziční parametry a ostatní budou posunuty tak, že původní parametr číslo 3 bude nyní 1, z $4 se stane $2, z $5 bude $3 atd. Pokud zadáte shift bez parametru (bez čísla), bude efekt stejný jako při zadání shift 1. Předveďme si to opět na příkladu:

#!/bin/bash
echo "Na začátku: "$@
echo "Počet parametrů: "$#
while [ "$#" != "0" ]; do
shift
echo "Po shiftu: "$@
sleep 1
done

Skript můžete spustit s libovolným počtem parametrů. Nejprve budou všechny vypsány ($@) a určen jejich počet ($#). Potom bude zahájena smyčka while (viz 13. díl), která bude probíhat, dokud bude počet parametrů různý od nuly. Uvnitř smyčky se nejprve provede samotný shift (bez parametru, tj. o jedno místo) a následně se se vypíše seznam parametrů po shiftu. Aby byl zdůrazněn průběh jednotlivými cykly, je každý ukončen vteřinovým spánkem (sleep 1).

Už umíme vytvořit skript reagující na parametry zadané z příkazové řádky. Příští díl pak bude opakovací. To znamená, že si na konkrétním skriptu ukážeme, co jsme se dosud naučili.