Shellové skripty mohou být napsány tak, aby běžely na různých platformách. Pokud se zaměříme jenom na GNU/Linux, i zde narazíme na spoustu odlišných prostředí, Linux běží na nejrůznějších síťových zařízeních, fiber switchích, routerech, atd. Přenositelný skript by mohl běžet i na FreeBSD, HP-UXu, AIXu, Solarisu a podobně. Je potřeba dát pozor na několik věcí:
Skript může běžet v různých podmínkách/prostředích, např. skript odladíte, ale při spuštění cronem přestane fungovat. Často bývá problém ve spolehnutí se na nějakou proměnnou prostředí.
Občas se člověk zapotí pokud by rád použil speciální znaky, jejichž zápis je nutné zahájit znakem zpětné lomítko \.
Příklad: Chci spustit skript na vzdáleném terminálu pomocí SSH. To se provede jednoduše příkazem:
ssh uživatel@server "příkaz"
Kamenem úrazu jsou zde příkazy v "uvozovkách", které kde se různé proměnné ovšem rozvinou nejprve v lokálním shellu, a teprve pak se provedou na vzdáleném stroji.
$ ssh bruchano@vzdaleny.stroj.cz "echo $HOME" /home/bruxy $ ssh bruchano@vzdaleny.stroj.cz "echo \$HOME" /home/bruchano $ ssh bruchano@vzdaleny.stroj.cz 'echo $HOME' /home/bruchano
Při práci s řetězci se vyplatí hojně využívat uvozovky. Zkuste si následující příklad:
STRING="Feb 9 Syslog" $ echo $STRING Feb 9 Syslog $ echo "$STRING" Feb 9 Syslog
Bez uvozovek shell zruší mezery navíc. Jednou jsem psal skript pro zpracování logů, který přestal začátkem měsíce fungovat. Problém byl v tom, že pokud den byl 1. až. 9., pak za zkratkou měsíce byly dvě mezery, jinak pouze jedna ("Feb 10" vs. "Feb 9"). Porovnávání řetězce bez uvozovek tak způsobilo, že co mělo být shodné nebylo a blbá chyba byla rázem na světě.
V těchto i dalších případech se vyplatí při ladění spouštět skript voláním interpretru: bash -x ./mujskript, zde bash před každým voláním vypíše spouštěný příkaz. Díky tomu je vidět obsah proměnných, a lehce tak dohledáme, proč v n-té iteraci nějakého cyklu skript vypovídá poslušnost.
Bash je natolik populární, že některá rozšíření bereme jako samozřejmost. Jedná se zejména o práci s poli a sekvence. Při přenosu skriptu na POSIXový shell, pak zjistíme, že nefunguje {1..5} nebo chybí příkaz seq a jiné.
Blbu-vzornost je vlastnost, která pomůže uchránit uživatele skriptu, před tím, aby si jeho použitím ublížil. Vyžaduje skript zadat parametr při spuštění? Jak se zachová pokud ho pustíme bez parametru nebo s nějakou neočekávanou hodnotou? Vypíše chybovou hlášku a korektně se ukončí nebo vesele zasyflí systém?
Dokonce i sám programátor, který je zároveň uživatelem vlastního skriptu je na místě napsat skript blbu-vzdorně. Zejména, pokud skript spouštíme třeba jednou za měsíc, lehce během té doby zapomeneme jak jsme to vlastně se vstupem a spouštěním mysleli, musíme se znovu vrtat ve zdrojáku, vzpomínat co a jak, atd.
Především v případě, že skript zpracovává řádově hodně dat je dobré se při jeho tvoření zamyslet nad výkonem. Jestli skript běží 10 vteřin nebo 20 je mnohdy celkem jedno, ale 10 nebo 20 minut už je znát. Někdy je dobré se rozmyslet hned na začátku, zda by nebylo lepší využít jiný jazyk, ať už interpretovaný a nebo rovnou kompilovaný. Výkonnost se oproti shellu často zvýší mnohonásobně. Ovšem u kompilovaných jazyků většinou bývá zase vývoj časově náročnější.
Čím se dají zlepšit parametry výkonu?
cat soubor.txt | grep slovo grep slovo soubor.txt
A=$( echo "234.432*823.1" | bc) B=$( echo "123.321*823.1" | bc)než pokud by se zapsal takto:
read A B <<< $( bc <<< "234.432*823.1;123.321*823.1")