Linux: Kniha kouzel, vanilková příchuť 2.14 (15. července 2022)
Veškerá moc příkazové řádky/příkazového řádku přehledně, pro začátečníky i pokročilé

3. Bash

Podkapitoly: 3.1 Funkce a skripty; 3.2 Interaktivní režim;

Řada 2.x vanilkové příchuti Linuxu: Knihy kouzel je od 15. července 2022 do 1. března 2025 ve stavu dlouhodobé pasivní údržby; nahlášené chyby budou opravovány, ale aktivní vývoj se již věnuje jiným projektům. Máte-li zájem pokračovat v tvorbě Linuxu: Knihy kouzel pro novější verze linuxových operačních systémů, kontaktujte autora nebo rovnou vytvořte odnož.

1. Úvod

Bash je výchozí interpret příkazového řádku v Ubuntu (a většině dalších linuxů). Tato kapitola se zabývá jeho funkcemi, které nejsou pokryty v jiných kapitolách, zejména přepínači nastavení, prací s návratovým kódem příkazů a některými užitečnými rozvoji. Ostatní vlastnosti Bashe najdete v podkapitolách této kapitoly, popř. ve zcela samostatných kapitolách.

Interpret Bash je vyvíjen v rámci projektu GNU.

2. Definice

  • Návratový kód (exit status) je celočíselný kód (0 až 255) vracený každým příkazem (s výjimkou přiřazení do proměnné či definice funkce), který indikuje, zda příkaz ve své činnosti uspěl (0) nebo ne (1 až 255).
  • Podprostředí (subshell) je částečně izolované prostředí pro vykonávání příkazů. Příkazy v podprostředí se chovají, jako by byly spuštěny v novém, odděleném procesu, až na to, že získají kopii všech proměnných (tzn. nejen exportovaných), deskriptorů a nastavení interpretu. Jakékoliv změny proměnných či nastavení interpretu, které provedou, však nemají účinek mimo podprostředí (na to je třeba si dát pozor zvlášť u příkazu „read“). Podprostředí má jako celek svůj návratový kód a jako na celek na něj mohou být aplikována přesměrování.

3. Zaklínadla

3/1 Aktuální adresář

@přejít do uvedeného adresáře#1
cd [--] cesta
@přejít o úroveň výš#2
cd ..
@přejít do domovského adresáře#3
cd
@zjistit aktuální adresář#4
pwd⊨ /home/aneta
@přejít do předchozího aktuálního adresáře#5
cd - [>/dev/null]

3/2 Spouštění a řetězení příkazů

@spustit příkaz na pozadí (obecně/příklad)#1 (1)
příkaz s parametry nebo sestava s rourou & [promenna=$!]
sleep 5 | wc -c & sleeppid=$!
@spustit příkazy v podprostředí#2
( příkazy ) [přesměrování pro podprostředí] [& [promenna=$!]]
(LC_ALL=C; sort a.txt >seřazené-a.txt; sort b.txt >seřazené-b.txt)
@spuštěným příkazem nahradit tuto instanci interpretu#3 (2)
exec příkaz a parametry

3/3 Rozvoje (dosazení) na příkazové řádce

@kartézský součin alternativ (obecně/příklad)#1 (3)
[předpona]{alternativa1,alternativa2[,další-alternativa]}[přípona]
\"{Nazdar,ahoj}\ {světe,'dva světy'}\"⊨ "Nazdar světe" "Nazdar dva světy" "ahoj světe" "ahoj dva světy"
@sekvence celých čísel (obecně/příklady)#2 (4)
{počáteční-hodnota..limit[..skok]}
{-5..3}⊨ -5 -4 -3 -2 -1 0 1 2 3
{1..-1}⊨ 1 0 -1
{3..7..3}⊨ 3 6
{3..7..2}⊨ 3 5 7
@dosadit standardní výstup bloku příkazů#3 (5)
$(příkazy)
@dosadit výsledek celočíselného výrazu#4
$((výraz))
@dosadit pojmenovanou rouru vedoucí na vstup/výstup bloku příkazů#5
>(příkazy)
<(příkazy)
@dosadit jako parametry cesty neskrytých souborů a adresářů podle vzorků#6 (6)
[název-nebo-vzorek/]vzorek[/název-nebo-vzorek]

3/4 Zvláštní proměnné užitečné i v interaktivním režimu

@návratová hodnota posledního vykonaného příkazu#1 (7)
$?
@text posledního parametru posledního jednoduchého příkazu vykonaného na popředí#2
$_
@PID probíhajícího interpretu#3
$$
@pole návratových hodnot příkazů z poslední vykonané roury#4 (8)
${PIPESTATUS[index]}

3/5 true a false

@vyhodnotit celočíselný výraz (kvůli vedlejším efektům)(obecně/příklad)#1
true $((celočíselný výraz))
true $((++i))
@ignorovat parametry a uspět#2
true [libovolné parametry]
@ignorovat parametry a selhat s kódem 1#3
false [libovolné parametry]

4. Zaklínadla: Nastavení Bashe

4/1 Vypisování příkazů (např. pro ladění)

@vypisovat příkazy před vykonáním tak, jak byly zadány (zapnout/vypnout)#1
set -v
set +v
@vypisovat příkazy před vykonáním tak, jak budou vykonány (zapnout/vypnout)#2 (9)
set -x
set +x

4/2 Nastavení rozvoje cest a proměnných

@pokud vzorek při rozvoji cest neodpovídá žádné cestě: selhat s chybou (doporučuji)/předat vzorek tak, jak je (výchozí chování, nedoporučuji)/předat prázdný řetězec#1
shopt -s failglob
shopt -u failglob nullglob
shopt -s nullglob; shopt -u failglob
@konstrukci „**“ při rozvoji cest interpretovat jako libovolnou (i prázdnou) posloupnost adresářů (zapnout/vypnout)#2
shopt -s globstar
shopt -u globstar
@rozsahy ve vzorcích při rozvoji cest (např. „[A-Z]“) intepretovat: podle locale „C“/podle aktuálního locale#3
shopt -s globasciiranges
shopt -u globasciiranges
@zahrnout do rozvoje cest i skryté soubory a adresáře (zapnout/vypnout)#4 (10)
shopt -s dotglob
shopt -u dotglob
@velká a malá písmena při rozvoji cest: rozlišovat/nerozlišovat#5
shopt -s nocaseglob
shopt -u nocaseglob
@rozvoj neexistující proměnné: považovat za kritickou chybu/tiše ignorovat#6 (11)
set -u
set +u

4/3 Zapnout/vypnout rozvoje

@provádět rozvoj historie (zapnout/vypnout)#1
set -H
set +H
@provádět rozvoj složených závorek {} (zapnout/vypnout)#2
set -B
set +B
@provádět rozvoj cest (zapnout/vypnout)#3
set +f
set -f
@provádět rozvoje $-konstrukcí ve výzvě Bashe: zapnout (výchozí)/vypnout#4 (12)
shopt -s promptvars
shopt -u promptvars

4/4 Zpracování návratových kódů

@při chybě ukončit interpret (zapnout/vypnout)#1
set -e
set +e
@návratový kód vícenásobné roury se vezme: z prvního příkazu, který selhal/vždy z posledního příkazu roury#2
set -o pipefail
set +o pipefail
@uplatnit ukončení při chybě i na příkazy uvnitř substituce $() (zapnout/vypnout)#3
shopt -s inherit_errexit
shopt -u inherit_errexit
@v případě selhání příkazu „exec“ v neinteraktivním režimu: pokračovat ve skriptu/skončit#4
shopt -s execfail
shopt -u execfail

4/5 Ostatní

@symbolické odkazy v cestě k aktuálnímu adresáři: jednorázově rozvinout/pamatovat si (výchozí)#1
set -P
set +P
@kontrolovat velikost okna a aktualizovat zvláštní proměnné COLUMNS a LINES (zapnout/vypnout)#2
shopt -s checkwinsize
shopt -u checkwinsize
@příkazy „.“ a „source“ budou při hledání svého argumentu prohledávat: cesty v PATH a nakonec aktuální adresář (výchozí chování)/jen aktuální adresář#3
shopt -s sourcepath
shopt -u sourcepath
@příkaz „echo“ bez parametrů „-e“ a „-E“ sekvence se zpětným lomítkem: interpretuje/neinterpretuje#4
shopt -s xpkg_echo
shopt -u xpkg_echo
@při každém vytvoření či přiřazení proměnné či funkce z ní učinit proměnnou prostředí (zapnout/vypnout)#5
set -a
set +a
@řízení úloh příkazy „fg“ a „bg“ a zkratkou Ctrl+Z (zapnout/vypnout)#6
set -m
set +m
@už nenačítat další řádek příkazů; po vykonání příkazů z tohoto řádku skončit (zapnout/vypnout)#7
set -t
set +t
@přepsání existujícího souboru obyčejným přesměrováním výstupu (zakázat/povolit)#8
set -C
set +C
@pokud není argument příkazu cd nalezen jako adresář, zkusit dereferencovat proměnnou téhož názvu (zapnout/vypnout)#9
shopt -s cdable_vars
shopt -u cdable_vars

4/6 Řídicí proměnné

Popis proměnných PS0, PS1 a PS2 najdete v kapitole „Terminál“.

@pokud název příkazu neobsahuje lomítko a neodpovídá identifiátoru aliasu, funkce či vestavěného příkazu, hledat program ke spuštění v těchto adresářích#1
PATH="/cesta[:/další/cesta]"
@domovský adresář uživatele#2
HOME=/cesta
@pokud parametr příkazu „cd“ neobsahuje lomítko a neexistuje jako adresář v aktuálním adresáři, zkusit prohledat ještě tyto další adresáře#3
CDPATH="/cesta[:/další/cesta]"

5. Instalace na Ubuntu

GNU Bash a všechny příkazy použité v této kapitole jsou základními součástmi Ubuntu přítomnými i v minimální instalaci.

6. Tipy a zkušenosti

6/1 Časté chyby

Pozor na implicitní vznik podprostředí v některých situacích! Bash automaticky obklopí podprostředím každý příkaz dvou- či vícečlenné roury a také i jednoduchý příkaz spouštěný na pozadí. To znamená, že např. tento blok kódu vypíše „19“, protože přiřazení z konstrukce „:=“ zůstalo izolované v podprostředí:

unset a
true "${a:=12}" &
wait $!
printf %s\\n "${a:=19}"

Častěji se tato chyba vyskytuje ve formě pokusu o použití příkazu „read“ s rourou:

unset a
printf 99\\n | IFS= read -r a
printf %s\\n "$a"

V uvedeném příkladu zůstane hodnota „a“ nedefinovaná, protože ho Bash uzavře do samostatného podprostředí.

6/2 Kartézský součin (složené závorky)

[předpona]{alternativa-1,alternativa-2[,další-alternativa]}[přípona]

Operátor kartézského součinu slouží ke generování parametrů, kde se na určené místo textu parametru postupně dosazují zadané podřetězce v uvedeném pořadí, např.:

abe{ce,sa,,}da⊨ abeceda abesada abeda abeda

Podřetězce mohou být prázdné a mohou se opakovat; jejich zadané pořadí bude při generování vždy dodrženo. Rovněž předpona a přípona generovaného parametru mohou být prázdné, takže např. „""{,,}“ vygeneruje tři prázdné parametry.

Vyskytuje-li se v jednom parametru víc operátorů kartézského součinu, zpracují se jako zleva doprava vnořené cykly, např. takto:

abe{00x,10y}da{20x,30y}da
abe00xda{20x,30y}da abe10yda{20x,30y}da
abe00xda20xda abe00xda30yda abe10yda20xda abe10yda30yda

Uvnitř operátoru kartézského součinu můžete použít obvyklé způsoby odzvláštnění, nejčastěji budete potřebovat potlačit zvláštní význam znaku „,“, který zde normálně odděluje dosazované alternativy, a znaku mezera, který by jako oddělovač parametrů celý operátor přerušil.

printf %s\\n {"Ahoj, ","{}/"}{světe,"2 světy!"}

7. Další zdroje informací

8. Zákulisí kapitoly

V této verzi kapitoly chybí:

  • koprocesy
  • ulimit
  • enable (zakazování vestavěných příkazů)
  • některé varianty příkazu „trap“

Tato kapitola záměrně nepokrývá:

  • Práci s proměnnými (viz kapitolu Proměnné příkazy a interpretu)
  • Nastavení terminálu a výzvy (viz kapitolu Terminál)

Další poznámky:

  • Nastavení proměnné BASH_ENV umožňuje spustit „před-skript“ při spouštění skriptu.
1 Spuštění příkazu na pozadí nezmění „$?“ PID spuštěného procesu můžete přečíst ze zvláštní proměnné „$!“. Bezprostředně za znakem „&“ nesmí následovat další oddělovač příkazů jako „;“, „&&“ nebo „||“.
2 Příkaz „exec“ nelze použít s vestavěnými příkazy Bashe či s rourami.
3 Viz podrobnější vysvětlení v podsekci „Kartézský součin“.
4 Výchozí skok je 1, resp. -1; nové parametry se generují, dokud je vygenerovaná hodnota ≤ (pro záporný skok ≥) zadanému „limitu“. Pokud se počáteční hodnota a limit rovnají, výsledkem bude jedno číslo (tzn. jeden parametr).
5 Uvedené příkazy se spouštějí v podprostředí; návratová hodnota podprostředí je ignorována (neuloží se do $? a neovlivní proměnnou PIPESTATUS). Pozor: jakkoliv dlouhá sekvence znaků „\n“ na konci dosazovaného výstupu bude při dosazení vynechána!
6 Vzorkem se rozumí parametr, který obsahuje jako zvláštní znak „?“, „*“ nebo konstrukci „[]“ tvořící syntakticky platný vzorek bashe. Skryté soubory a adresáře jsou normálně ignorovány, pokud vzorek pro odpovídající část cesty nezačíná tečkou. Výsledný seznam parametrů se seřadí podle abecedy podle aktuální lokalizace.
7 Metapříkaz „!“ umí negovat návratový kód při ukládání do $?, viz kapitolu Metapříkazy.
8 Poznámka: jednoduchý příkaz toto pole přepíše jednoprvkovým polem; obsah pole PIPESTATUS není nikdy ovlivněn metapříkazem „!“.
9 Pozor, tato varianta vypisuje i jednotlivé příkazy vykonávané při dosazování operátorem $(), což může vyprodukovat velké množství rušivého výstupu.
10 Zvláštní položky „.“ a „..“ stále nebudou zahrnuty, pokud vzorek nezačíná tečkou.
11 Nedoporučuji používat nastavení „-u“ v interaktivním režimu, protože kód pro doplňování příkazové řádky obsahuje velké množství chyb v adresaci proměnných, a když na ně narazíte, příjdete o celou řádku, kterou jste se pokusil/a doplnit.
12 Poznámka: vypnutí těchto rozvojů nevypne nativní rozvoje specifické pro výzvu interpretu (tzn. např. za „\w“ se i nadále bude dosazovat aktuální adresář), ale nebudou se rozvíjet vnořené proměnné apod.
Líbí se vám tento projekt a chcete, aby byl ještě lepší? Můžete mi s tím pomoci. Zmiňte se o něm technicky zdatným přátelům, opravte překlepy a nahlašte nefunkční zaklínadla, aby mohla být opravena; poskytněte mi zpětnou vazbu nebo se zapojte do vývoje nových kapitol. Další informace na GitHubu v dokumentu Jak se zapojit.
[BY-SA]

Veškerý obsah této stránky (text, obrázky, zdrojový kód) je možno upravovat a šířit pod podmínkami licence Creative Commons Attribution-ShareAlike 4.0 International. Upozorňuji, že uvedená licence vyžaduje uvedení seznamu autorů, licence a zdroje a poskytnutí stejné či kompatibilní licence k provedeným změnám, jsou-li nějaké. Příslušné údaje jsou dostupné na stránce „Přehled autorů“. Šíření obsahu bez těchto údajů nebo šíření upravené verze bez poskytnutí adekvátní licence k provedeným úpravám je pravděpodobně porušení licenčních podmínek a může být postihováno. Poskytování zdrojového kódu při šíření není touto licencí vyžadováno.

Pro nové verze, další informace, aktuální zdrojový kód a možnost se zapojit do projektu „Linux: Kniha kouzel“ navštivte jeho repozitář na GitHubu.