Aritmetické expanze
Jak jsme si již řekli, expanze v Bashi znamená nahrazení nějakého zástupného řetězce jeho logickým významem (hodnotou) - např. hodnota proměnné, výsledek provedení nějakého příkazu nebo regulárního výrazu, doplnění cesty k souboru apod. V případě aritmetických expanzí jde o náhradu matematického výrazu jeho výsledkem. Výraz přitom zapisujeme do dvojitých závorek následovně: $((vyraz)) - např. tak můžeme zadat echo $(( 3 * 3 )). Možná vám až dech vyrazí, jaké Bash umí výrazy. Vedle klasických +, -, *, / jsou to:
$((a++)), resp. $((a--)) - vypíše hodnotu proměnné a a následně ji zvýší (resp. sníží) o jedničku.
$((++a)), resp. $((--a)) - nejprve zvýší (resp. sníží) hodnotu proměnné a o jedničku a potom tuto novou hodnotu vypíše.
$((2**3)) - třetí mocnina dvou, tj. 2 na třetí (8).
$((7%2)) - výsledkem je zbytek po dělení 7/2. Jak jsem již zmínil, Bash umí pracovat jen s celými čísly, proto jako výsledek dělení 7/2 vrátí 3, zbytek (7%2) bude 1.
$((a==5)) - vyhodnotí, zda se hodnota proměnné a rovná číslu 5. Výsledkem tohoto výrazu je pravda (1) nebo nepravda (0). Obdobně funguje vyhodnocování nerovností (!=, <=, >=, <, >).
$((4<<1)) - provede bitový posun doleva, tedy 3. bit (hodnota 4) o 1, tj. na 4. bit (hodnota 8) a výsledkem bude 8.
$((4>>1)) - provede bitový posun doprava, tedy 3. bit (hodnota 4) o 1, tj. na 2. bit (hodnota 2) a výsledek je 2.
$((5&6)) - bitové AND, vypíše hodnotu společných bitů, v našem případě 5 (1. a 3. bit) a 6 (2. a 3. bit) je společný 3. bit, tedy hodnota 4.
$((5|6)) - bitové OR, vypíše hodnotu bitů, které se vyskytují alespoň na jedné straně, v tomto případě 5 (1. a 3. bit) a 6 (2. a 3. bit) jsou použity bity 1, 2 a 3, tedy hodnota 1+2+4=7.
$((5^6)) - bitové exkluzivní OR, vypíše hodnotu bitů, které se vyskytují pouze na jedné nebo pouze na druhé straně, zde tedy 5 (1. a 3. bit) a 6 (2. a 3. bit) má společný bit 3 a exkluzivní zůstávají 1 a 2, dohromady 3.
$((a&&b)) - logické AND, nabývá hodnoty 1, pokud jsou hodnoty a i b nenulové, jinak nabývá hodnoty 0.
$((a||b)) - logické OR, nabývá hodnoty 1, pokud alespoň jedna z hodnot a a b je nenulová, jinak nabývá hodnoty 0.
Další aritmetickou konstrukcí, kterou Bash zvládá, je kondiční operátor. Jeho zápis má podobu vyraz1?vyraz2:vyraz3. Funguje tak, že pokud platí podmínka ve vyraz1 (výsledkem je nenulová hodnota), je proveden vyraz2, jinak se provede vyraz3. Např. echo $((a==6?a:a++)) vypíše hodnotu a pokud se rovná 6, jinak také vypíše hodnotu a a poté ji zvýší o jedničku.
Ještě zmíním skupinu konstrukcí označovaných za přiřazovací. V podstatě jde o většinu zde zmíněných operandů doplněných znakem rovnítko. Např. prostý zápis a=5 přiřadí proměnné a hodnotu 5, zatímco a+=3 vypíše hodnotu a poté, co k ní připočte číslo 3. K dispozici jsou vedle aritmetických (*= /= %= += -=) také konstrukce logické (<<= >>= &= ^= |=).
Speciální znaky
V posledních třech dílech jsme se věnovali operacím, které provádí Bash se vstupem z příkazové řádky. Ukázali jsme si jednoduché i složitější konstrukce. Nepohovořili jsme však o třech znacích se zvláštním významem: obrácené lomítko (\), apostrof (') a uvozovky ("). Bash tyto znaky zadané na příkazové řádce (tedy ne takové, které vznikly v důsledku expanzí) odstraní.
Uvozovky slučují do jednoho bloku (pozičního parametru) skupinu znaků obsahující např. mezery, a přitom zaručují provedení expanzí (náhrada jmen proměnných za jejich hodnoty apod.) Apostrofy také slučují skupinu znaků dohromady, ale zabrání provedení případných expanzí, takže řetězec bude použit přesně tak, jak byl zadán. Obrácené lomítko potlačuje speciální význam bezprostředně následujícího zadaného znaku, kterým může být #, $, &, *, ale i závorka, mezera nebo další obrácené lomítko.
To je asi tak všechno, co Bash dělá se vstupem na příkazové řádce před samotným provedením zadaného příkazu. Protože tento seriál není překladem manuálové stránky ani referenční příručkou, neobsahuje úplně všechny mechanismy. Bádavý uživatel tak může najít mechanismy typu Process Substitution nebo bitová a logická negace. Příště si ukážeme, jak si v Bashi, resp. shellovém skriptu, nadefinovat vlastní funkce.