Skip to content

Latest commit

 

History

History
499 lines (359 loc) · 19.7 KB

bash.md

File metadata and controls

499 lines (359 loc) · 19.7 KB

Bash

!Štítky: {program}{bash} !OblíbenáZaklínadla: !ÚzkýRežim: zap

Ú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.

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í.

!ÚzkýRežim: vyp

Zaklínadla

Aktuální adresář

# přejít do uvedeného adresáře
cd [--] {cesta}

# přejít o úroveň výš
cd ..

# přejít do domovského adresáře
cd

# zjistit aktuální adresář
pwd ⊨ /home/aneta

# přejít do předchozího aktuálního adresáře
cd - [>/dev/null]

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

# spustit příkaz na pozadí (obecně/příklad)
// 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 „||“.
{příkaz s parametry nebo sestava s rourou} & [{promenna}=$!]
sleep 5 | wc -c & sleeppid=$!

# spustit příkazy v podprostředí
( {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
// Příkaz „exec“ nelze použít s vestavěnými příkazy Bashe či s rourami.
exec {příkaz a parametry}

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

# kartézský součin alternativ (obecně/příklad)
// Viz podrobnější vysvětlení v podsekci „Kartézský součin“.
[{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)
// 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).
{{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ů
// 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!
$({příkazy})

# dosadit výsledek celočíselného výrazu
$(({výraz}))

# dosadit pojmenovanou rouru vedoucí na vstup/výstup bloku příkazů
>({příkazy})
<({příkazy})

# dosadit jako parametry cesty neskrytých souborů a adresářů podle vzorků
// 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.
[{název-nebo-vzorek}/]...{vzorek}[/{název-nebo-vzorek}]...

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

# návratová hodnota posledního vykonaného příkazu
// Metapříkaz „!“ umí negovat návratový kód při ukládání do $?, viz kapitolu Metapříkazy.
$?

# text posledního parametru posledního jednoduchého příkazu vykonaného na popředí
$_

# PID probíhajícího interpretu
$$

# pole návratových hodnot příkazů z poslední vykonané roury
// Poznámka: jednoduchý příkaz toto pole přepíše jednoprvkovým polem; obsah pole PIPESTATUS není nikdy ovlivněn metapříkazem „!“.
${PIPESTATUS[{index}]}

true a false

# vyhodnotit celočíselný výraz (kvůli vedlejším efektům)(obecně/příklad)
true $(({celočíselný výraz}))
true $((++i))

# ignorovat parametry a uspět
true [{libovolné parametry}]

# ignorovat parametry a selhat s kódem 1
false [{libovolné parametry}]

Zaklínadla: Nastavení Bashe

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

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

# vypisovat příkazy před vykonáním tak, jak budou vykonány (zapnout/vypnout)
// 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.
set -x
set +x

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
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)
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
shopt -s globasciiranges
shopt -u globasciiranges

# zahrnout do rozvoje cest i skryté soubory a adresáře (zapnout/vypnout)
// Zvláštní položky „.“ a „..“ stále nebudou zahrnuty, pokud vzorek nezačíná tečkou.
shopt -s dotglob
shopt -u dotglob

# velká a malá písmena při rozvoji cest: rozlišovat/nerozlišovat
shopt -s nocaseglob
shopt -u nocaseglob

# rozvoj neexistující proměnné: považovat za kritickou chybu/tiše ignorovat
// 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.
set -u
set +u

Zapnout/vypnout rozvoje

# provádět rozvoj historie (zapnout/vypnout)
set -H
set +H

# provádět rozvoj složených závorek {} (zapnout/vypnout)
set -B
set +B

# provádět rozvoj cest (zapnout/vypnout)
set +f
set -f

# provádět rozvoje $-konstrukcí ve výzvě Bashe: zapnout (výchozí)/vypnout
// 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.
shopt -s promptvars
shopt -u promptvars

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

# při chybě ukončit interpret (zapnout/vypnout)
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
set -o pipefail
set +o pipefail

# uplatnit ukončení při chybě i na příkazy uvnitř substituce $() (zapnout/vypnout)
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
shopt -s execfail
shopt -u execfail

Ostatní

# symbolické odkazy v cestě k aktuálnímu adresáři: jednorázově rozvinout/pamatovat si (výchozí)
set -P
set +P

# kontrolovat velikost okna a aktualizovat zvláštní proměnné COLUMNS a LINES (zapnout/vypnout)
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ář
shopt -s sourcepath
shopt -u sourcepath

# příkaz „echo“ bez parametrů „-e“ a „-E“ sekvence se zpětným lomítkem: interpretuje/neinterpretuje
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)
set -a
set +a

# řízení úloh příkazy „fg“ a „bg“ a zkratkou Ctrl+Z (zapnout/vypnout)
set -m
set +m

# už nenačítat další řádek příkazů; po vykonání příkazů z tohoto řádku skončit (zapnout/vypnout)
set -t
set +t

# přepsání existujícího souboru obyčejným přesměrováním výstupu (zakázat/povolit)
set -C
set +C

# pokud není argument příkazu cd nalezen jako adresář, zkusit dereferencovat proměnnou téhož názvu (zapnout/vypnout)
shopt -s cdable_vars
shopt -u cdable_vars

Ří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
PATH="{/cesta}[:{/další/cesta}]..."

# domovský adresář uživatele
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
CDPATH="{/cesta}[:{/další/cesta}]..."

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.

!ÚzkýRežim: zap

Tipy a zkušenosti

Č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í.

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!"}

Další zdroje informací

Zákulisí kapitoly

V této verzi kapitoly chybí:

!KompaktníSeznam:

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

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

!KompaktníSeznam:

  • 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:

!KompaktníSeznam:

  • Nastavení proměnné BASH_ENV umožňuje spustit „před-skript“ při spouštění skriptu.

!ÚzkýRežim: vyp