Lekce 2 - Skriptování v Bashi - Proměnné
V předchozí lekci, Skriptování v Bashi - Úvod do skriptování, jsme si vysvětlili rozdíl mezi kompilovaným a skriptovacím jazykem. Naučili jsme se, k čemu můžeme využít Bash a napsali si první skript.
V tomto tutoriálu skriptování v Bashi si vysvětlíme, co je to proměnná, jak s ní pracovat a k čemu ji při skriptování budeme potřebovat.
Co je to proměnná
Proměnná je místo v paměti, kterému přiřadíme nějakou hodnotu. Na rozdíl od matematiky, kde proměnná je část rovnice či vzorce, v programování můžeme jednu proměnnou, resp. hodnotu v ní uchovanou, použít na několika místech programu nebo i v několika programech.
A to je přesně ten důvod, proč chceme v programování používat proměnné. Lidé jsou od přírody leniví a hledají cesty, jak si usnadnit, urychlit a zefektivnit práci. Nemusíme říkat počítači, co má udělat pokaždé, když to potřebujeme. Můžeme tuto informaci uchovat např. v proměnné a celý proces si následně zautomatizovat.
Přiblížíme si to na příkladu. Máme program, který po spuštění vypíše uvítací větu se jménem přihlášeného uživatele:
Vítej uživateli ITnetwork!
Jednou z variant řešení je toto jméno napsat ručně pro každého
uživatele zvlášť. Je to prakticky nemožný úkol, protože bychom museli
pro každého uživatele napsat vlastní program. Výrazně použitelnější
variantou je vytvořit místo v paměti (proměnnou)
pojmenovanou např. UZIVATEL
, které budeme
přiřazovat jako hodnotu jméno právě
přihlášeného uživatele:
UZIVATEL=ITnetwork #k této proměnné se přiřadí jméno právě přihlášeného uživatele
Místo jména uživatele pak napíšeme do věty název proměnné. V tu chvíli je nám jedno, kdo zrovna spustil program, protože se vždy použije to správné jméno.
Hodnota proměnné UZIVATEL
se v paměti udrží, jen
dokud program běží. Toto je velmi důležité. Pokud by proměnné
zůstávaly uchovány v paměti počítače i po ukončení programu, za chvilku
bychom měli paměť plnou a počítač by přestal fungovat.
Systémové proměnné a Bash
V Linuxu se budeme často setkávat s tzv. systémovými proměnnými. Jsou
to proměnné pracující na úrovní operačního systému. Často slouží pro
jeho správnou funkčnost. Nejprve si vypíšeme do terminálu všechny naše
systémové proměnné příkazem printenv
:
itnetwort@itnetwork:~$ printenv
V konzoli vidíme výstup:
Konzolová aplikace
SHELL=/bin/bash
HOME=/home/itnetwork
LANG=en_US.UTF-8
USER=itnetwork
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
…
Každý řádek začíná názvem proměnné, následuje =
jako
znak přiřazení a hodnota, která je proměnné přiřazená. Např.
proměnné USER
je přiřazena hodnota názvu našeho
uživatelského účtu, v tomto případě itnetwork
. Zkusíme si
tuto hodnotu rovnou vypsat do konzole. Před název napíšeme znak dolaru
$
. Tím řekneme shellu, že máme na mysli proměnou:
itnetwort@itnetwork:~$ echo "Vítej uživateli $USER!"
V konzoli vidíme výstup:
Konzolová aplikace
Vítej uživateli itnetwork!
Stejně tak můžeme použít proměnnou i ve skriptu:
itnetwort@itnetwork:~$ touch pozdrav.sh itnetwort@itnetwork:~$ echo "echo Vítej uživateli $USER!" >> pozdrav.sh itnetwort@itnetwork:~$ bash script.sh
V konzoli vidíme výstup:
Konzolová aplikace
Vítej uživateli itnetwork!
V příkladu jsme nenapsali příkaz do skriptu přes textový editor, ale
pomocí echo
. Příkazem echo
s přesměrováním
výstupu pomocí >>
, vložíme nový řádek na konec
skriptu. Je to další možnost, jak si můžeme zefektivnit práci, případně
jak zapisovat skriptem do jiného souboru.
Nesmíme ale zaměnit >>
za pouze jeden
znak >
, který by obsah celého našeho skriptu přepsal.
Příkaz export
Může se stát, že jednu hodnotu potřebujeme použít ve více skriptech.
V každém skriptu bychom si mohli vytvořit proměnnou s touto hodnotou, ale to
není efektivní. Pokud bychom pak potřebovali tuto hodnotu nahradit jinou,
museli bychom ji přepsat v každém skriptu zvlášť. Místo toho si
vytvoříme novou systémovou proměnnou. K ní pak budou moci přistupovat
všechny programy. Slouží k tomu příkaz export
:
itnetwort@itnetwork:~$ export CINNOST="Učím se skriptovat v Bashi."
Po vypsání proměnného prostředí příkazem printenv
uvidíme v seznamu námi nově vytvořenou proměnnou. Můžeme si ji zkusit
vypsat do terminálu:
itnetwort@itnetwork:~$ echo $CINNOST
V konzoli uvidíme:
Konzolová aplikace
Učím se skriptovat v Bashi.
Vytvoření proměnné by stejně tak fungovalo i bez použití
export
. Ovšem bylo by platné pouze pro aktuálně
přihlášeného uživatele. Pokud bychom se přihlásili jako
root
, proměnná by již nefungovala. Nově vytvořená systémová
proměnná platí pouze pro aktuální shell a vypnutím systému zanikne.
Změna systémové proměnné
Příkazem export můžeme také přepsat hodnotu systémové proměnné.
Řekněme, že bychom potřebovali spouštět náš skript v domovském
adresáři z různých míst našeho systému. Pokud nechceme pokaždé psát
celou cestu ke skriptu, potřebujeme zapsat novou cestu do systémové
proměnné PATH
. Do této proměnné se zapisují cesty a Linux se
sem dívá vždy, když zadáme příkaz do terminálu. V případě, že tento
program na jedné z cest najde, spustí ho. V opačném případě vrátí chybu
command not found
.
Vytvoříme si nový skript s pozdravem v dokumentech našeho domovského
adresáře a přidáme mu práva ke spuštění. Můžeme spojit příkazy v
jeden pomocí tzv. pipe
(pajpy):
itnetwort@itnetwork:~$ touch $HOME/Dokumenty/pozdrav.sh | echo "echo Vítej uživateli $USER!" >> $HOME/Documenty/pozdrav.sh | chmod u+x $HOME/Documenty/pozdrav.sh
Když se nyní přesuneme do základní struktury příkazem
cd /
a zkusíme spustit náš script zadáním jeho názvu, shell
nám vrátí chybu, že příkaz nezná. Musíme tedy přidat cestu do
proměnné PATH
:
itnetwort@itnetwork:~$ export PATH=$PATH:/home/itnetwork/Dokumenty
Příkazem export
jsme vytvořili novou proměnnou s již
existujícím názvem PATH
. Tím jsme přepsali tu původní. Jako
novou hodnotu jsme zvolili původní hodnotu a navíc k ní přidali další
cestu. Každá cesta v PATH
je oddělená dvojtečkou:
itnetwort@itnetwork:~$ echo $PATH
Výstup v konzoli vypadá takto:
Konzolová aplikace
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/home/itnetwork/Dokumenty
Nyní můžeme spouštět skript pouhým zadáním jeho názvu z jakéhokoliv místa systému. Jak jsme si již řekli, proměnná zůstává v paměti pouze do doby, než program skončí. V tomto případě do vypnutí systému.
Skript může spouštět pouze uživatel, který k tomu má oprávnění. V našem případě pouze vlastník.
Proměnné ve skriptu
Nyní si ukážeme, jak pracovat s proměnnou přímo ve skriptu. Funguje to
prakticky stejně, jako u systémové proměnné, jen není zapotřebí příkaz
export
. Použít ji však můžeme pouze uvnitř skriptu:
#!/bin/bash JMENO=ITnetwork echo "Hodnota proměnné JMENO je $JMENO"
Výstup v konzoli vypadá takto:
Konzolová aplikace
Hodnota proměnné JMENO je ITnetwork
Velká písmena v názvech proměnných nejsou povinná. Stejně tak budou fungovat i malá písmena. Ovšem z hlediska lepší čitelnosti kódu je dobré tuto konvenci zachovat. Pozor, Bash je tzv. case sensitive. To znamená, že zápisy názvů proměnných JMENO a Jmeno jsou různé:
#!/bin/bash JMENO=ITnetwork Jmeno=Linux echo "Hodnota proměnné JMENO je $JMENO" echo "Hodnota proměnné Jmeno je $Jmeno"
Výstup v konzoli vypadá takto:
Konzolová aplikace
Hodnota proměnné JMENO je ITnetwork
Hodnota proměnné Jmeno je Linux
Hodnotu, kterou proměnné přiřadíme, můžeme dále v kódu přepisovat:
#!/bin/bash JMENO=ITnetwork echo "Hodnota proměnné JMENO je $JMENO" JMENO=David echo "Hodnota proměnné JMENO je $JMENO"
Po spuštění skriptu získáme tento výstup:
itnetwort@itnetwork:~$ bash script.sh
Hodnota proměnné JMENO je ITnetwork
Hodnota proměnné JMENO je David
Jako hodnotu můžeme přiřadit i jinou proměnnou:
#!/bin/bash JMENO1=ITnetwork JMENO2=$JMENO1 echo "Hodnota proměnné JMENO2 je $JMENO2"
Výstup v konzoli vypadá takto:
Konzolová aplikace
Hodnota proměnné JMENO2 je ITnetwork
Zakázané názvy proměnných
Jak již víme, název proměnné může obsahovat velká i malá písmena. Pro lepší čitelnost je lepší volit velká písmena. Název může obsahovat i čísla:
Jmeno1=ITnetwork #Toto je zcela legitimní způsob zápisu.
Problém nastává ve chvíli, kdy proměnná začíná číslicí, po níž následují písmena. Takovýto název Bash neuzná. Dále nejsou povoleny speciální znaky. Jediný povolený znak je _:
1UZIVATEL=ITnetwork #neplatný název proměnné JMENO-UZIVATELE=ITnetvork #neplatný název proměnné JMENO_UZIVATELE=ITnetwork #platný název proměnné
Nyní tedy ovládáme základní práci s proměnnými. V dalších lekcích tyto znalosti často využijeme.
V příští lekci, Skriptování v Bashi - Uživatelský vstup a početní operace, si ukážeme, jak si vyžádat vstup od uživatele a jak tento vstup použít dále ve skriptu. Také se naučíme základní matematické operace v Bashi.