19.
Proměnné prostředí a interpretu
1. Úvod
Tato kapitola pokrývá veškerou práci s proměnnými a funkcemi interpretu Bash a uvádí některé systémově důležité proměnné prostředí. Rovněž pokrývá práci s parametry skriptů a funkcí v Bashi.
Proměnné se v bashi (zejména ve skriptech a funkcích) používají k dočasnému uchování krátkých textových dat (popř. čísel) mezi příkazy. Většina proměnných je viditelná pouze v rámci dané instance interpretu; pro práci s prostředím se používají „exportované“ proměnné, které instance bashe vytvoří z proměnných prostředí v momentě svého spuštění a ze kterých sestaví prostředí každého procesu, který spustí.
GNU Bash je vyvíjen v rámci projektu GNU.
2. Definice
- Bash rozeznává tři základní typy proměnných: řetězcové proměnné, pole (indexované celými čísly od nuly) a asociativní pole (indexované neprázdným řetězcem zvaným klíč).
- Prostředí je soubor řetězcových proměnných (tzv. proměnných prostředí), který má nejen bash, ale každý proces (s výjimkou jaderných démonů). Prostředí se kopíruje do každého nově spuštěného procesu a bash ho reprezentuje souborem exportovaných proměnných, což umožňuje prostředí nově vytvořených procesů měnit.
- Funkce je krátký skript, který se místo do souboru ukládá do paměti (stejně jako proměnná). Na rozdíl od skutečného skriptu se vždy spouští v rámci stávající instance bashe. Stejně jako skript lze funkci zavolat zadáním jejího názvu jako příkazu a má svoje poziční parametry. Funkce se často používají ve skriptech jako podprogramy, ale užitečné jsou i v interaktivním režimu.
- Konstanta je proměnná (jen zřídka exportovaná), které je jednorázově přidělena hodnota a dále již nemůže být změněna ani zrušena.
- Parametry (také poziční parametry) jsou v bashi přístupné jako zvláštní proměnné „1“, „2“ atd. Poziční parametry lze číst všemi způsoby, jakými lze číst obyčejné proměnné, ale přiřadit lze jen do všech najednou, a to voláním skriptu, volání funkce nebo příkazem „set“.
- Celočíselné proměnné jsou řetězcové proměnné a prvky polí či asociativních polí, kterým byl nastaven atribut „i“. Při každém přiřazení do takové proměnné (resp. prvku) se přiřazovaný text vyhodnotí jako celočíselný výraz a do proměnné/prvku se přiřadí výsledná celočíselná hodnota.
Názvy proměnných a funkcí jsou obvykle tvořeny jen velkými a malými písmeny anglické abecedy, podtržítky a číslicemi, přičemž nesmí začínat číslicí.
3. Zaklínadla: Proměnné v bashi
3/1 Řetězcové proměnné
3/2 Exportování proměnných
3/3 Obecné
3/4 Pole (jako celek)
3/5 Pole (práce s prvky)
3/6 Asociativní pole (jako celek)
3/7 Asociativní pole (práce s klíči a prvky)
Pozor! Klíčem v asociativním poli může být pouze neprázdný řetězec! Prázdný klíč způsobí chybu „chybný podskript pole“.
3/8 Funkce
3/9 Celočíselné proměnné
3/10 Jmenné odkazy
3/11 Konstanty
4. Zaklínadla: Dosazování proměnných
4/1 Jednoduché a nepřímé dosazení
4/2 Vlastnosti proměnné
4/3 Podmíněné dosazení
4/4 Dosazení podřetězce či se substitucí
4/5 Poziční parametry
4/6 Aritmetické operace při dosazení
4/7 Různé příklady
5. Zaklínadla: Proměnné prostředí
5/1 Spouštění programů s upraveným prostředím
5/2 Předdefinované proměnné
/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
5/3 Proměnné ovládající programy a systém
5/4 Preferované aplikace
Poznámka: proměnné prostředí EDITOR, VISUAL a PAGER se obvykle nastavují v souboru „~/.bashrc“.
5/5 Prostředí jiných procesů
5/6 Proměnné pro programátory
6. Instalace na Ubuntu
Všechny použité nástroje jsou základní součástí Ubuntu, přítomné i v minimální instalaci.
7. Tipy a zkušenosti
- Pozor! Kolem znaku „=“ při přiřazování do proměnných nesmí být žádné bílé znaky! Jedinou výjimkou je tzv. aritmetický kontext (tedy např. uvnitř konstrukce „$(( prom = 1 + 1 ))“).
- Náhradní řetězce a vzorky v pokročilých formách dosazení (např. „${X%.txt}“) vytvářejí nový kontext pro odzvláštnění, ve kterém můžete použít podle potřeby zpětná lomítka, uvozovky, apostrofy, a dokonce vnořené dosazení proměnných! Takže chcete-li např. dosadit hodnotu proměnné X po odebrání podřetězce „%\}“ z jejího konce, použijte tvar "${X%'%\}'}".
- Do řetězcových proměnných můžete ukládat jakékoliv znaky UTF-8 kromě nulového bajtu, takže konce řádek, tabulátory, Escape apod. nejsou žádný problém.
- Pokud potřebujete v asociativním poli použít jako klíč prázdný řetězec (což není dovoleno), pomůže upravit kód tak, aby před každý klíč vkládal konkrétní písmeno (např. „X“) a před výpisem toto písmeno zase odstraňoval (např. „${klíč#X}“).
- Velkými písmeny (např. HOME či HISTSIZE) se píšou názvy proměnných, které mají řídicí či systémový význam, ať už jde o proměnné prostředí či jen interpretu. Vaše uživatelské proměnné ve skriptech nazývejte malými písmeny (např. „cesta_zpet“), popř. kombinací malých a velkých písmen (např. „CestaZpet“).
- Znak ~ se v bashi rozvíjí na hodnotu „${HOME}“, proto ho uvnitř dvojitých uvozovek (kde by se nerozvinul) můžete vždy snadno a bezpečně nahradit za „${HOME}“.
- Funkce se může jmenovat stejně jako proměnná.
- V bashi vznikají proměnné automaticky při prvním přiřazení, není tedy třeba je deklarovat. Ve výchozím nastavení navíc pokus o dosazení neexistující proměnné povede k dosazení prázdného řetězce bez jakékoliv chyby (toto lze změnit nastavením „set -u“).
- Při čtení prostředí ostatních procesů je třeba si dát pozor na to, že bash změny exportovaných proměnných nereflektuje do svého vlastního prostředí, ale až do prostředí procesů, které spustí (počítá se i spuštění příkazem „exec“).
8. Další zdroje informací
- YouTube: Programování v Shellu (proměnných se týká začátek videa)
- Linuxexpres: Proměnné prostředí
- YouTube: Fedora Linux Proměnné (jen úplné základy)
- Wikipedie: Proměnná
- Ubuntu Documentation: EnvironmentVariables (anglicky)
- Bash Reference Manual: Shell Parameter Expansion (anglicky)
- TL;DR: env (anglicky)
9. Zákulisí kapitoly
V této verzi kapitoly chybí:
- zvláštní proměnné interpretu Bash, které řídí jeho funkci, ale nebývají proměnnými prostředí
- lokální proměnné ve funkcích (pokryty nedostatečně)
- možnosti přednastavení proměnných v souborech jako /etc/environment, „.profile“ či „.bashrc“
Tato kapitola záměrně nepokrývá:
- zvláštní parametry (jako např. $?, $! apod.)
- pattern matching (patřil by do jiné kapitoly)