## Ako písať dobré bash skripty miroslav.binas@tuke.sk / [**OSS Conf 2018**](http://ossconf.soit.sk/)
## Miesto agendy * nie som nadšený _bash ~~striptér~~ skriptér_ * sú situácie, kedy sa použitie `bash`-u vyslovene nehodí * je to však fantastický nástroj na prepájanie rozličných riešení * _glue_ * _swiss army knife_ každého _DevOps_-áka * nasledujúci zoznam odporúčaní nie je kompletný
## #1 Nezabúdajte na prenositeľnosť!
### Prenositeľný _Hello world!_ ```bash #!/usr/bin/env bash echo "Hello world!" ``` * `env` - run a program in a modified environment * ak je parametrom príkaz, nájde prvú binárku v premennej `PATH` a spustí ju * spoľah na umiestnenie `/usr/bin/env`
## #2 Pri výskyte chyby sa musí skript zastaviť!
### Zlý skript ```bash #!/usr/bin/env bash echo "start here" VAR = "syntax error on this line" echo "this line will be executed too" ```
### Začnite takto ```bash #!/usr/bin/env bash set -o errexit # stop when error occurs set -o pipefail # if not, expressions like `error here | true` # will always succeed set -o nounset # detects uninitialised variables set -o xtrace # prints every expression # before executing it (debugging) echo "start here" VAR = "syntax error on this line" echo "this line is now not reachable" ```
## #3 Uzatvárajte premenné do `"${variable}"`
* _escaping_ * úvodzovky pomôžu pri premenných, ktoré obsahujú medzery * zložené zátvorky nie sú úplne potrebné, ale používajú sa pri tzv. _bash expansion_ * interpolácia reťazcov - `"${variable}.yml"` * predvolená (fallback) hodnota - `"${variable:-something_else}"` * náhrada reťazcov - `"${variable//from/to}"`
## #4 Používajte `[[ ]]` miesto `[ ]` (`[[` - rozšírenie bash-u, `[` - skrátený zápis príkazu `test`)
### Mocné vychytávky * premenné netreba uzatvárať do úvodzoviek ```bash [[ -f ${file} ]] # vs. [ -f "${file}" ] ``` * podporuje operátory `&&` a `||` a porovnávanie reťazcov pomocou operátorov `<` a `>` * zaviedol operátor `=~` pre porovnávanie na základe regulárnych výrazov ```bash [[ ${answer} =~ ^y(es)?$ ]] ``` * podporuje _globbing_ ```bash [[ ${answer} = y* ]] ```
## #5 Píšte skripty modulárne
* miesto písania všetkého do jedného súboru ho uložte do viacerých (modulov) * jednoduchšia údržba a navigácia * logicky uzavretá (a oddelená) funkcionalita * vkladanie/rozšírenie existujúceho skriptu o nový docielite príkazom `source` ```bash # ... source "${DATADIR}/helper.sh" # ... ```
## #6 Nepoužívajte nástroje, ktorých funkcie `bash` zvláda
* jedna z najčastejších (nevedomých) chýb * najčastejšie `grep`, `awk`, `sed`, `bc`, `expr`, napr.: ```bash size=$(du -hs images/ | awk '{print $1}') ``` vyriešiť pomocou ```bash array=($(du -hs images/)) size=${array[0]} ``` * namiesto `seq 1 10` použite `{1..10}` * používajte `$()` miesto ``
## #7 Píšte skripty tak, aby sa dali testovať
* "mocný" prístup - všetko uzavrieť do funkcie ```bash #!/usr/bin/env bash main(){ echo "Hello world!" } main ``` * existuje mnoho nástrojov pre podporu testovania v bash-i (napr. [bats](https://github.com/sstephenson/bats)) ```bash #!/usr/bin/env bats @test "when new folder is created, then exit status is 0" { run mkdir "${dir}" assert_equal "${status}" 0 } ```
## #8 Používajte linter
> **Linter** je program, ktorý skontroluje kód na prítomnosť _programátorských_ a _štýlových_ chýb, čím pomáha zvýšiť kvalitu kódu.
### [ShellCheck](https://www.shellcheck.net/) * Shell script analysis tool * obsahuje tzv. [galériu zlého kódu](https://github.com/koalaman/shellcheck/blob/master/README.md#user-content-gallery-of-bad-code), ktorá vám ukáže, čo všetko vám môže `ShellCheck` pomôcť identifikovať * nachádza sa vo vašej distribúcii
## Ostatné odporúčania * deklarácia konštánt ```bash readonly var='immutable value' ``` * písanie vlastných funkcií ```bash _greetings(){ local name="$1" printf "%s\n" "${name}" } ```
## Questions?
![qr code](https://api.qrserver.com/v1/create-qr-code/?data=http://bit.ly/2ku8ZO6&size=300x300) (**http://bit.ly/2ku8ZO6**)