Skip to content

Latest commit

 

History

History
716 lines (529 loc) · 34.9 KB

proměnné.md

File metadata and controls

716 lines (529 loc) · 34.9 KB

Proměnné prostředí a interpretu

!Štítky: {tematický okruh}{bash}{systém} !OblíbenáZaklínadla: !ÚzkýRežim: zap

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

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

!ÚzkýRežim: vyp

Zaklínadla: Proměnné v bashi

Řetězcové proměnné

# přiřadit proměnné hodnotu
{název_proměnné}="{nová-hodnota}"

# zrušit proměnnou
// Pozor! Příkaz „unset“ uspěje i tehdy, pokud daná proměnná neexistuje.
unset -v {název_proměnné}

# vypsat seznam (s hodnotami/bez hodnot/s hodnotami ve formátu txtz)
for _ in $(compgen -v); do [[ ${!_@a} = *[aA]* ]] || declare -p "$_"; done
for _ in $(compgen -v); do [[ ${!_@a} = *[aA]* ]] || printf '%s\n' "$_"; done
for _ in $(compgen -v); do [[ ${!_@a} = *[aA]* ]] || printf '%s=%s\0' "$_" "${!_}"; done

# připojit text na začátek/konec proměnné
{název_proměnné}="{nová-hodnota}${název_proměnné}"
{název_proměnné}+="{nová-hodnota}"

# jde o řetězcovou proměnnou? (alternativy)
[[ -v {název_proměnné} && ${{název_proměnné}@a} = *([!aA]) ]]
[[ -v {název_proměnné} && ${{název_proměnné}@a} =~ ^[^aA]*$ ]]

# automatická konverze velikosti písmen při přiřazení (na velká písmena/na malá písmena/vypnout)
// Pozor! Zapnutí této konverze nezmění stávající hodnotu proměnné, účinek nastane až při následujícím přiřazení!
declare -u {název_proměnné}...
declare -l {název_proměnné}...
declare +lu {název_proměnné}...

Exportování proměnných

# exportovat/neexportovat proměnnou
export {název_proměnné}[={nová-hodnota}]
export -n {název_proměnné}...

# jde o exportovanou/neexportovanou proměnnou?
[[ ${{název_proměnné}@a} = *x* ]]
[[ -v {název_proměnné} && ! ${{název_proměnné}@a} = *x* ]]

# seznam exportovaných proměnných (s hodnotami/bez hodnot)
(set -o posix; declare -x)
compgen -e

# seznam neexportovaných proměnných (s hodnotami/bez hodnot)
(set -o posix; declare +x)
for _ in $(compgen -v); do [[ ${!_@a} = *x* ]] || printf '%s\n' "$_"; done

Obecné

# jde o proměnnou?
test -v {název_proměnné}

# seznam všech proměnných (s hodnotami/bez hodnot)
(set -o posix; set)
compgen -v

# dosadit názvy všech proměnných, které začínají určitou předponou
// Názvy proměnných se dosadí jako samostatné parametry (podobně jako u speciálního parametru $@).
${!{předpona}@} ⊨ PATH PIPESTATUS PPID PROMPT_COMMAND PS1 PS2 PS4 PWD

Pole (jako celek)

# vytvořit či přepsat/zrušit/vyprázdnit
// Prvky pole se zadávají stejně jako parametry příkazu, tzn. oddělují se mezerami; obsahují-li zvláštní znaky, budou interpretovány, pokud je neodzvláštníte (vhodné je umístění do uvozovek či apostrofů).
{název_pole}=([{prvky}]...)
unset -v {název_pole}
{název_pole}=()

# seznam polí (bez hodnot)
compgen -A arrayvar

# dosadit počet prvků
${#{názevpole}[@]}

# jde o pole?
[[ ${{název_proměnné}@a} = *a* ]]

# zkopírovat (celé pole/výřez)
{cílové_pole}=("${{zdrojové_pole}[@]}")
{cílové_pole}=("${{zdrojové_pole}[@]:{první-kopírovaný-index}[:{maximální-počet}]}")

# spojit dvě pole
{cílové_pole}=("${{první_pole}[@]}" "${{druhé_pole}[@]}")

# rozdělit pole na poloviny
{první_cíl}=("${{názevpole}[@]:0:$((${#{název_pole}[@]}/2+1))}")
{druhý_cíl}=("${{názevpole}[@]:$((${#{název_pole}[@]}/2+1))}")

# obrátit pořadí prvků pole
// V případě potřeby změňte názvy pomocných proměnných „i“, „j“ a „x“.
i=-1 j=${#{název_pole}[@]}
while test $((++i)) -lt $((--j))
do
x=${{název_pole}[i]}
{název_pole}[i]=${{název_pole}[j]}
{název_pole}[j]=$x
done
[unset -v i j x]

# přiřadit do pole parametry skriptu či funkce
{cílové_pole}=("$@")

Pole (práce s prvky)

# přečíst prvek na indexu N/přiřadit do něj
// Je dovoleno přiřadit do prvku libovolně daleko za koncem pole; Bash v takovém případě pole automaticky prodlouží prázdnými řetězci, aby index byl platný.
${{název_pole}[{N}][-{náhradní hodnota}]}
{název_pole}[{N}]={hodnota}

# iterovat přes prvky/přes indexy
for {iterační_proměnná} in "${{název_pole}[@]}"; do {...}; done
for {iterační_proměnná} in "${!{název_pole}[@]}"; do {...}; done

# dosadit výřez pole
// Výřez se dosadí jako samostatné parametry (podobně jako u zvláštního parametru $@).
"${{zdrojové_pole}[@]:{první-kopírovaný-index}[:{maximální-počet}]}"

# vložit nový prvek na začátek/konec
// Pozor! Vkládání prvků na začátek je v případě rozsáhlého pole velmi pomalé! Snažte se mu vyhnout a vkládat prvky raději na konec. Pro vložení prvku doprostřed použijte spojování polí (které je ale také pomalé).
{název_pole}=("{nový prvek}" "${{název_pole}[@]}")
{název_pole}+=("{nový prvek}")

# odstranit N prvků na začátku/konci
{název_pole}=("${{názevpole}[@]:{N}}")
{název_pole}=("${{názevpole}[@]:0:$((${#{název_pole}[@]}-{N}))}")

Asociativní pole (jako celek)

# vytvořit = vyprázdnit
unset -v {název} && declare -A {název}

# zrušit
unset -v {název}

# jde o asociativní pole?
[[ ${{název_proměnné}@a} = *A* ]]

# seznam asociativních polí (bez hodnot)
for _ in $(compgen -v); do [[ ! ${!_@a} = *A* ]] || printf '%s\n' "$_"; done

# dosadit počet prvků
${#{název}[@]}

# zkopírovat
unset -v {cílovépole}
declare -A {cílovépole}
for _ in "${!{zdrojovépole}[@]}"; do cílovépole[$_]=${{zdrojovépole}[$_]}; done

# sloučit dvě asociativní pole
for _ in "${!{zdrojovépole}[@]}"; do cílovépole[$_]=${{zdrojovépole}[$_]}; done

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

# přečíst hodnotu prvku (klíč je řetězec/hodnota proměnné)
// Tyto tvary uvádějte vždy ve dvojitých uvozovkách. Klíč se v tomto případě vyhodnocuje, jako by byl sám uvnitř samostatných dvojitých uvozovek, což umožňuje i vícenásobné vnoření této konstrukce, ačkoliv to je špatně čitelné.
["{...}]${{názevpole}["{klíč}"]}[{...}"]
["{...}]${{názevpole}["${klíč_proměnná}"]}[{...}"]

# přiřadit hodnotu prvku (klíč je: řetězec/hodnota proměnné)
// Uvozovky kolem klíče slouží pouze k odzvláštnění znaků klíče, můžete je odzvláštnit i jinak, např. zpětným lomítkem či apostrofy.
{názevpole}["{klíč}"]="{hodnota}"
{názevpole}[${klíč_proměnná}]="{hodnota}"

# obsahuje prvek se zadaným klíčem? (klíč je hodnota proměnné)
test -v "{názevpole}[${{proměnná_s_klíčem}@Q}]"

# obsahuje prvek se zadaným klíčem? (klíč je řetězec)
: '{klíč}' [&&]
test -v "{názevpole}[${_@Q}]"

# dosadit klíče/hodnoty
"${!{název_pole}[@]}"
"${{název_pole}[@]}"

# iterovat přes klíče/přes hodnoty
for {iterační_proměnná} in "${!{název_pole}[@]}"; do {...}; done
for {iterační_proměnná} in "${{název_pole}[@]}"; do {...}; done

# odstranit prvek podle klíče (klíč je hodnota proměnné)
unset -v "{názevpole}[${{proměnná_s_klíčem}@Q}]"

# odstranit prvek podle klíče (klíč je řetězec)
: "{klíč}" [&&]
unset -v "{názevpole}[${_@Q}]"

# příklady: přiřadit do proměnné „x“ hodnotu z asociativního pole „a“, kde klíčem je: zpětné lomítko/dvě zpětná lomítka/apostrof/dvojitá uvozovka/„A B“/„} }“
x="${a["\\"]}"
x="${a["\\\\"]}"
x="${a["'"]}"
x="${a["\""]}"
x="${a["A B"]}"
x="${a["} }"]}"

Funkce

# vytvořit/přepsat funkci
// Pokud je uzavírací závorka „}“ na stejném řádku jako poslední příkaz těla funkce, musí být od příkazu oddělená středníkem.
function {název_funkce} {
[{tělo-funkce}]
}

# zavolat funkci
{název_funkce} [{parametry}]...

# seznam funkcí (s těly/bez těl)
declare -f
compgen -A function

# existuje funkce?
declare -f {název_funkce} >/dev/null

# zrušit funkci
unset -f {název_funkce}

# vypsat definici funkce
declare -f {název_funkce}

# exportovat/neexportovat funkci
// Exportované funkce se uloží do zvláštních proměnných prostředí a další instance bashe, která je tímto způsobem „zdědí“, je opět načte jako funkce. Doporučuji exportování funkcí příliš nepoužívat, protože tak můžete snadno ztratit kontrolu nad tím, kam všude se vaše funkce dostanou.
export -f {název_funkce}
export -fn {název_funkce}

Celočíselné proměnné

# jde o celočíselnou proměnnou?
// Tento test odpoví kladně i v případě, že půjde o pole celočíselných hodnot či asociativní pole celočíselných hodnot.
[[ ${{název_proměnné}@a} = *i* ]]

# nastavit řetězcovou proměnnou jako celočíselnou (obecně/příklady...)
// Hodnoty přiřazené do celočíselných proměnných se automaticky vyhodnocují jako výrazy a konvertují na celé číslo. Místo každého druhého názvu proměnné v uvedeném příkazu pochopitelně můžete uvést novou hodnotu proměnné, a to i výrazem.
declare -i {název_proměnné}=${název_proměnné} [{další_proměnná}=${další_proměnná}]...
declare -i x=$x
declare -i x=-1

# nastavit pole či asociativní pole, že jeho prvky budou celočíselné
// Pozor! Účinek této deklarace nastává až při následujícím přiřazení. Pokud tedy deklarované pole či asociativní pole již obsahuje neceločíselné hodnoty, zůstanou v původní podobě, dokud nebudou přepsány!
declare -i {název_pole_či_asoc_pole}...

# přičíst/odečíst od celočíselné proměnné
: $(({název_proměnné} += {číslo}))
: $(({název_proměnné} -= {číslo}))

Jmenné odkazy

# vytvořit jmenný odkaz
// Poznámka: jmenným odkazem nelze odkazovat na normální ani asociativní pole!
declare -n {název_odkazu}={název_odkazované_proměnné}

# zrušit jmenný odkaz
unset -n {název_odkazu}

# je proměnná jmenný odkaz?
test -R {název_proměnné}

# přečíst jmenný odkaz místo odkazované proměnné (alternativy)
if test -R {název_odkazu}; then declare +n {název_odkazu}; echo ${název_odkazu}; declare -n {název_odkazu}; else false; fi
test -R {název_odkazu} && eval "$(declare -p {název_odkazu} | sed -E '1s/^[^=]*=/echo␣/')"

Konstanty

# seznam konstant (pro člověka/bez hodnot)
readonly
for _ in $(compgen -v); do [[ ! ${!_@a} = *r* ]] || printf '%s\n' "$_"; done

# jde o konstantu?
[[ ${{název_proměnné}@a} = *r* ]]

# vytvořit konstantu
// Konstanta je proměnná interpretu (popř. prostředí), kterou nelze zrušit ani později změnit její hodnotu (bez použití opravdu škaredých a nespolehlivých hacků). Lze ji však změnit z proměnné interpretu na proměnnou prostředí a naopak. Jde-li o proměnnou prostředí, vytvořené procesy (včetně dalších instancí bashe) ji zdědí již jako obyčejnou (přiřaditelnou) proměnnou prostředí.
readonly {název_konstanty}="{hodnota}" [{další_název_konstanty}="{hodnota}"]...

Zaklínadla: Dosazování proměnných

Jednoduché a nepřímé dosazení

# dosadit hodnotu řetězcové proměnné (alternativy)
${název_proměnné} ⊨ Hello, world!
${{název_proměnné}}

# dosadit hodnotu řetězcové proměnné s odzvláštněním
// Hodnota bude typicky v apostrofech či konstrukci „$''“. Konkrétní tvar se může lišit, ale vždy bude možno ho bezpečně dosadit do skriptu.
${{název_proměnné}@Q} ⊨ 'Hello, world!'

# nepřímé dosazení
// Tuto konstrukci lze skombinovat s většinou ostatních druhů dosazení.
${!{proměnná}[{zbytek výrazu}]}

# dosadit prvky pole (všechny prvky/jeden prvek/výřez/poslední prvek)
"${{název_pole}[@]}"
"${{název_pole}[{index}]}"
"${{název_pole}[@]:{první-kopírovaný-index}[:{maximální-počet}]}"
"${{název_pole}[-1]}"

# dosadit hodnotu z asociativního pole (klíč je řetězec/hodnota proměnné)
// Tyto tvary uvádějte vždy ve dvojitých uvozovkách. Klíč se v tomto případě vyhodnocuje, jako by byl sám uvnitř samostatných dvojitých uvozovek, což umožňuje i vícenásobné vnoření této konstrukce, ačkoliv to je špatně čitelné.
${{název_asoc_pole}["{klíč}"]}
${{název_asoc_pole}["${klíč_proměnná}"]}

# dosadit všechny klíče/všechny hodnoty z asociativního pole
"${!{název_asoc_pole}[@]}"
"${{název_asoc_pole}[@]}"

Vlastnosti proměnné

# dosadit délku hodnoty proměnné ve znacích
${#{název_proměnné}} ⊨ 0

# dosadit znaky reprezentující zapnuté atributy dané proměnné
// Nemá-li proměnná zapnutý žádný atribut, dosadí se prázdný řetězec.
${{název_proměnné}@a} ⊨ x

# dosadit příkaz bashe, který vytvoří danou proměnnou včetně atributů a hodnoty
${{název_proměnné}@A} ⊨ declare -x HOME='/home/kalandira'

Podmíněné dosazení

# je-li proměnná definovaná/neprázdná, dosadit; jinak použít náhradní řetězec
// Pokud má náhradní řetězec obsahovat zvláštní znaky či znak „}“, doporučuji uzavřít jej do dvojitých uvozovek. To funguje i tehdy, pokud je dosazovací výraz jako celek použit uvnitř dvojitých uvozovek.
${{název_proměnné}-["]{náhradní řetězec}["]}
${{název_proměnné}:-["]{náhradní řetězec}["]}

# dosadit hodnotu proměnné, která musí být definovaná/neprázdná; jinak zobrazit chybové hlášení a ukončit skript
${{název_proměnné}?["]{chybové hlášení}]["]}
${{název_proměnné}:?["]{chybové hlášení}]["]}

# je-li proměnná definovaná/neprázdná, dosadit; jinak jí přiřadit náhradní hodnotu a dosadit
${{název_proměnné}=["]{náhradní řetězec}["]}
${{název_proměnné}:=["]{náhradní řetězec}["]}

# dosadit řetězec, jen pokud je proměnná definovaná/neprázdná
// Nebude-li splněna podmínka dosazení, dosadí se prázdný řetězec.
${{název_proměnné}+["]{řetězec}["]}
${{název_proměnné}:+["]{řetězec}["]}

Dosazení podřetězce či se substitucí

# dosadit podřetězec hodnoty proměnné
// Tip: kolem indexu a délku mohou být mezery, kolem názvu proměnné ne.
${{název_proměnné}: {index-prvního-znaku-od-0} : {maximální-délka} }

# dosadit hodnotu proměnné po odebrání nejkratší/nejdelší shody začátku hodnoty se vzorkem
${{název_proměnné}#{vzorek}}
${{název_proměnné}##{vzorek}}

# dosadit hodnotu proměnné po odebrání nejkratší/nejdelší shody konce hodnoty se vzorkem
${{název_proměnné}%{vzorek}}
${{název_proměnné}%%{vzorek}}

# dosadit hodnotu proměnné po nahrazení první/všech shod se vzorkem řetězcem náhrady
${{název_proměnné}/{vzorek}[/{řetězec náhrady}]}
${{název_proměnné}//{vzorek}[/{řetězec náhrady}]}

# dosadit hodnotu proměnné velkými/malými písmeny
${{název_proměnné}^^}
${{název_proměnné},,}

# interpretovat hodnotu jako by byla uvedena v konstrukci $'text' a výsledek dosadit
${{název_proměnné}@E}

Poziční parametry

# dosadit N-tý poziční parametr (alternativy)
// První variantu lze použít pouze pro parametry $0 až $9. Druhou variantu (tu se složenými závorkami) lze použít i pro ostatní parametry (např. ${10}) a lze ji skombinovat s pokročilými formami dosazení.
${N}
${{N}}

# dosadit všechny parametry od $1: do samostatných parametrů/jen oddělené mezerou
// Dvojité uvozovky zde znamenají, že pro správnou funkci musí být $@ (resp. $*) uvedeny uvnitř dvojitých uvozovek.
"$@"
"$*"

# dosadit počet pozičních parametrů
$# ⊨ 0

# smazat N pozičních parametrů počínaje od $1, zbytek přečíslovat
// Výchozí N je 1. Pokud je pozičních parametrů méně než N, příkaz selže s návratovým kódem 1 a poziční parametry zůstanou nezměněné.
shift [{N}]

# nastavit poziční parametry
// Parametry lze nastavit pouze najednou, přičemž se všechny stávající parametry (kromě $0) ztratí.
set -- {parametr}...

# dosadit úsek parametrů (samostatně/oddělené mezerou)
"${@: {číslo-prvního-parametru} [: {maximální-počet}] }"
"${*: {číslo-prvního-parametru} [: {maximální-počet}] }"

# dosadit všechny parametry počínaje $0 (samostatně/oddělené mezerou)
"${@:0}"
"${*:0}"

Aritmetické operace při dosazení

# inkrementovat/dekrementovat a dosadit
$((++{název_proměnné}))
$((--{název_proměnné}))

# přičíst/odečíst číslo, přiřadit a dosadit
$(({název_proměnné} += {číslo}))
$(({název_proměnné} -= {číslo}))

# přičíst/odečíst číslo a dosadit (bez přiřazení)
$(({název_proměnné} + {číslo}))
$(({název_proměnné} - {číslo}))

Různé příklady

# dosadit první neprázdnou z proměnných „a“, „b“ a „c“
${a:-${b:-${c:-}}}

# dosadit proměnnou „abc“ s odstraněním všech konců řádků
${abc//$'\n'}

# dosadit proměnnou „abc“ s tím, že všechny číslice se nahradí nulami
${abc//[0123456789]/0}

# z proměnné „abc“ dosadit jen číslice
${abc//[!0123456789]}

Zaklínadla: Proměnné prostředí

Spouštění programů s upraveným prostředím

# spustit s upraveným prostředím (jednodušší varianta)
[[/usr/bin/]env] {PROMĚNNÁ}={hodnota} [{DALŠÍ_PROMĚNNÁ}={další-hodnota}]... {příkaz} [{parametr}]...

# spustit v jiném aktuálním adresáři
env -C {cesta} {příkaz} [{parametr}]...

# spustit s upraveným prostředím (komplexní varianta)
// -i prostředí zcela vyprázdní; --unset z něj odebírá uvedené proměnné, přiřazení proměnné prostředí nastavuje a parametr „-C“ změní aktuální adresář.
[[/usr/bin/]env [-i] [--unset={PROMĚNNÁ}]... [-C {nový/aktuální/adresář}]] [{PROMĚNNÁ}={hodnota}]... {příkaz} [{parametr}]...

Předdefinované proměnné

# absolutní cesta domovského adresáře
$HOME ⊨ /home/petr

# vyhledávací cesty externích příkazů
// Cesty jsou odděleny. Bývají absolutní, ale mohou být i relativní. Zahrnout aktuální adresář „.“ je možné, ale z bezpečnostních důvodů se to striktně nedoporučuje.
$PATH ⊨ /home/petr/bin:/usr/local/sbin:/usr/local/bin:
/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

# označení příslušného grafického zobrazovacího rozhraní
$DISPLAY ⊨ :0.0

# typ terminálu
// Pro textovou konzoli je to „linux“. Další hodnoty, se kterými se lze setkat, jsou „xterm“ a „rxvt“.
$TERM ⊨ xterm-256color

# typ sezení
// Jde-li o X-server, hodnota je „x11“, pro Wayland je to „wayland“, v textové konzoli je to „tty“.
$XDG_SESSION_TYPE ⊨ x11

# jazyk/lokalizace systému
$LANGUAGE ⊨ cs_CZ
$LANG ⊨ cs_CZ.UTF-8

# výchozí interpret příkazové řádky
$SHELL ⊨ /bin/bash

# uživatelské jméno
// Poznámka: proměnnou prostředí lze snadno podvrhnout. Pro bezpečné zjištění uživatelského jména použijte příkaz „id -un“.
$USER ⊨ petr

# adresář pro dočasné soubory
${TMPDIR-/tmp}

Proměnné ovládající programy a systém

# vypnout lokalizaci a podporu Unicode
// Tato volba se zapíná především při řazení, kdy způsobí, že soubor se seřadí podle kódových hodnot bajtů. Hodí se také pro dosažení vyššího výkonu některých skriptovacích nástrojů, ale tam je potřeba, aby uživatel věděl, co dělá.
LC_ALL=C

# vypnout lokalizaci, ale ponechat kódování UTF-8
LC_ALL=C.UTF-8

# preferovaná časová zóna
TZ=UTC
TZ=Europe/Prague

# nelokalizovat výpisy a hlášení
LC_MESSAGES=C.UTF-8

# požádat aplikaci o použití určitého dočasného adresáře
TMPDIR={/absolutní/cesta}

Preferované aplikace

Poznámka: proměnné prostředí EDITOR, VISUAL a PAGER se obvykle nastavují v souboru „~/.bashrc“.

# výchozí textový editor (terminálový/grafický)
EDITOR=/bin/nano
VISUAL=/usr/bin/gedit

# výchozí terminálový stránkovač
PAGER=/usr/bin/less

Prostředí jiných procesů

# mohu číst prostředí daného procesu?
test -r /proc/{PID}/environ

# vypsat seznam proměnných
sed -zE 's/=.*//' /proc/{PID}/environ | tr \\0 \\n [| sort]

# je proměnná definovaná/neprázdná?
egrep -zq '^{název_proměnné}=' /proc/{PID}/environ
egrep -zq '^{název_proměnné}=.' /proc/{PID}/environ

# přečíst hodnotu
sed -znE 's/^{název_proměnné}=//;T;p' /proc/{PID}/environ | tr -d \\0

Proměnné pro programátory

# cesty pro vyhledávání sdílených knihoven
// Když spuštěný program požádá systém o nahrátí sdílené knihovny, systém ji obvykle vyhledává v několika standardních adresářích. Má-li však program v prostředí proměnnou „LD_LIBRARY_PATH“, systém nejprve prohledává adresáře uvedené zde. V každém případě nahraje první nalezenou knihovnu a případné další knihovny téhož jména ignoruje.
LD_LIBRARY_PATH={cesta}[:{další/cesta}]...

# vypsat ladicí informace ohledně sdílených knihoven
// Nápovědu k proměnné LD_DEBUG si můžete zobrazit příkazem „env LD_DEBUG=help cat“. Bez proměnné LD_DEBUG_OUTPUT se ladicí údaje vypíšou na standardní výstup; s ní se k jejímu obsahu připojí tečka a PID procesu a výpis se provede do daného souboru.
LD_DEBUG=libs[,symbols] [LD_DEBUG_OUTPUT={předpona/výstupní/cesty}]

# vynutit načtení funkcí ze zadané sdílené knihovny do aplikace (nezkoušeno, bez záruky).
LD_PRELOAD=/home/petr/moje.so

Instalace na Ubuntu

Všechny použité nástroje jsou základní součástí Ubuntu, přítomné i v minimální instalaci.

!ÚzkýRežim: zap

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“).

Další zdroje informací

Zákulisí kapitoly

V této verzi kapitoly chybí:

!KompaktníSeznam:

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

!KompaktníSeznam:

  • zvláštní parametry (jako např. $?, $! apod.)
  • pattern matching (patřil by do jiné kapitoly)

!ÚzkýRežim: vyp