Lekce 10 - Linuxový terminál (Bash) - Standardní vstup/výstup a expanze
V minulé lekci, Linuxový terminál (Bash) - Práce s procesy, jsme si vysvětlili rozdíl mezi procesem, úlohou a úkol. Dále jsme se zabývali uspořádáním procesů v Linuxu a jejich následnou správou.
V dnešní lekci se zaměříme na standardní vstup/výstup a vysvětlíme si pojem expanze.
Standardní vstup a výstup
V Linuxu existují pojmy standardní výstup a
standardní vstup. Jedná se o základní datové
proudy, se kterými pracuje většina linuxových programů.
Čtou z nich data nebo do nich data naopak zapisují. Ve
výchozím nastavení je standardní výstup připojený na konzoli a
standardní vstup na klávesnici. Takto jsme komunikovali například s
programem ls
, který vypsal obsah složky na standardní výstup,
tedy do konzole:
Přesměrování výstupu
Standardní výstup můžeme pro daný program přesměrovat a to pomocí
operátoru >
, případně >>
. Zkusme si
to:
Do konzole se nyní nevypsalo nic a ve složce se naopak objevil soubor
vypis.txt
, který se pro program choval jako standardní výstup a
proto je v něm výpis složek. Soubor můžeme otevřít například v
geditu
nebo v nano
:
Pokud použijeme operátor >
, soubor se vždy přepíše. S
operátorem >>
se připisuje na konec souboru (append) a jeho
obsah se tedy nemaže.
Přesměrování vstupu
Podobně, jako výstup, můžeme přesměrovat i vstup. Nemělo by vás
překvapit, že toho docílíme pomocí znaku <
. Možná vás
napadá k čemu je to dobré, když uživatel téměř vždy zadává
klávesnicí. Jako vstup můžeme určitě použít textový soubor nebo dokonce
výstup nějakého jiného programu.
Jako ukázka nám poslouží naprosto jednoduchý výpis hlavičky souboru.
Hlavičkou je myšleno prvních 10 řádků a vypíšeme ji příkazem
head
. Jako vstup ji nasměrujeme náš soubor z předešlé
ukázky:
Výstup můžeme klidně opět přesměrovat do dalšího souboru:
Roury (pipelines)
Když lze přesměrovat vstup i výstup nějakého příkazu, neměl by být
problém propojit 2 příkazy tak, aby druhý zpracovával výstup toho
prvního. Příkazy propojíme pomocí hezky expresivně nazvané trubky, kterou
zapíšeme svislítkem (|
). Můžete se setkat i s označením
roura nebo "pajpa" od anglického pipe.
Na příkladu si vypišme obsah složky do prohlížeče textových souborů
less
. Výhodou je, že můžeme výpisem jednoduše
stránkovat:
Trubek můžeme použít hned několik, udělejme si stejný příklad s tím
rozdílem, že výpis z ls
pošleme filtru head
,
který ořízne jen prvních 10 řádků a ty pošleme druhou trubkou
less
:
Filtry
Mnoho příkazů (nebo obecně programů) přijímá data na standardním vstupu, tato data nějak zpracuje a výsledek odešle na výstup. Takovým příkazům se někdy říká filtry a se znalostí přesměrování vstupů/výstupů a trubek jsou velmi užitečné. Zmiňme si alespoň některé z nich:
cat |
Cat je zkratka z concatenate, tedy spojit. Jedná se o program, který načte jeden nebo více souborů a pošle je na standardní výstup. Můžeme pomocí něj soubory i vytvářet. Soubory předáme jednoduše v parametrech, pokud jich předáme více, spojí se do jednoho delšího textu. |
cut |
Cut umožňuje již podle názvu nařezat vstupní text a to například podle bajtů, znaků nebo sloupců. |
fmt |
Zformátuje daný text, aby byl lidsky lépe čitelný. Často se používá například pro zalomení odstavců na určitou délku řádku. |
grep |
Vypíše řádky ze vstupu, které odpovídají zadanému formátu. Můžeme zde použít i regulární výrazy. |
head |
Vypíše prvních 10 řádků ze vstupu. |
pr |
Připraví text pro tisk a to zejména tak, že ho rozdělí na jednotlivé stránky. |
sort |
Setřídí řádky textu na vstupu podle abecedy a pošle je na výstup. |
uniq |
Pokud filtru předáme setříděný soubor, odstraní z něj duplicitní řádky. |
tail |
Vypíše posledních 10 řádků ze vstupu. |
tr |
Tr je odvozeno z translate a umožňuje nahradit znaky ve vstupním textu. Můžeme nahrazovat určitá slova nebo třeba vše převést na velká písmena. |
awk |
Implementace jazyka AWK pro zpracovávání textových souborů. |
sed |
Pokročilejší verze příkazu tr . |
Expanze
Již víme, že v shellových příkazech můžeme používat
speciální znaky. Zatím jsme se takto setkali např. s
*
nebo s ?
. Než je takový příkaz vykonán, je
shellem nejprve zpracován a proběhne tzv. expanze.
Různé zkrácené zápisy a značky jsou v tu chvíli převedeny na
jejich výsledek.
Na expanzi se můžeme velmi jednoduše podívat a to pomocí příkazu
echo
. Ten možná znáte z Windows a vykonává jen jednu
jednoduchou úlohu - vypíše text předaný v parametru do standardního
výstupu. Nejprve si ho vyzkoušejme:
Nyní si vypišme, jak shell vidí například příkaz
cp -r * slozka
:
Vidíme, že se hvězdička přeložila (expandovala) na názvy všech
souborů a složek, které jsou zde umístěné. Samozřejmě si můžete
vyzkoušet i další kombinace, například echo *.txt
, což se
expanduje jen na textové soubory v aktuální složce.
Tilda
Tilda (~
) se přeloží na domovskou složku
aktuálního nebo zadaného uživatele:
Složené závorky
Pokud ve výrazu použijeme složené závorky ({ }
),
vygeneruje se nám množina textových řetězců tak, aby se
vyčerpaly všechny možnosti, které v závorkách uvedeme.
Obrázek řekne více, než tisíc slov:
Vidíme, že nám Bash vygeneroval množinu řetězců, kde každý začíná
na slozka
a potom obsahuje jeden ze znaků v závorkách, které
jsme oddělili čárkou.
Uvnitř závorek můžeme používat i patterny jako
1..9
, A-F
nebo dokonce z-a
. Výsledek
samozřejmě nemusíme echovat, ale můžeme si nechat složky vytvořit:
Aritmetické výrazy
Bash za nás vyhodnotí i jednoduché matematické výrazy.
Bohužel umí pracovat jen s celými čísly. Výraz vložíme do notace
$()
a uvnitř ještě do jedné závorky:
Proměnné
Bash za nás expanduje spoustu proměnných. Ty se píší velkými písmeny
a začínají na znak dolaru. Seznam všech si můžeme vypsat pomocí příkazu
printenv
. Se znalostí trubek si je můžeme nechat seřadit podle
abecedy a otevřít v lessu:
Určitě jste si všimli proměnných USER
a HOME
.
Vypišme si je:
Příkazy
Do samotného příkazu můžeme vložit i výstup jiného příkazu. Neplést s "pajpou", kde jsme nasměrovali jeden program do druhého. Zde načítáme výstup programu a vkládáme ho jako část příkazu, který shell později spustí:
Místo syntaxe $()
lze alternativně použít i zpětné
uvozovky (`
).
Uvozovky a escapování
Bash bere bílé znaky jako oddělovače příkazů a jejich parametrů. Je
jedno kolik mezer nebo tabulátorů za sebe napíšeme, vždy je vyhodnotí jako
jedno oddělení. Použít mezeru jako součást příkazu by byl problém,
stejně jako použít nějaké z dalších speciálních znaků, jako jsou
($
) nebo zpětné uvozovky (`
):
Máme celkem 3 možnosti jak se s takovou situací vypořádat.
Dvojité uvozovky
Pokud vložíme část textu příkazu do dvojitých uvozovek, bude Bash
interpretovat $
, \
a `
. Ostatních věcí
jako ~
, mezer a podobně si nevšímá. Nejčastější využití
dvojitých uvozovek je zadání názvu souboru nebo složky, která má v názvu
mezeru. Mimochodem, takové složky pokud možno nevytvářejte, lidé ve vašem
okolí vám poděkují
Na obrázku výše vidíme i co se stane bez uvozovek. Bash vyhodnotí
slozka
jako druhý parametr příkazu ls
.
Můžeme si zkusit zapsat do dvojitých uvozovek například nějakou konstantu, abychom viděli, že se opravdu interpretuje:
Jednoduché uvozovky (apostrofy)
Výraz v jednoduchých uvozovkách se do shellu vloží přesně tak, jak je zapsaný. Expanze se nevyhodnotí a mezery se nesloučí:
Escapování
Jestli vás nepadlo co dělat, když potřebujeme někam zapsat uvozovky, tak
v této situaci použijeme tzv. escapování. Speciální znaky můžeme totiž
předsadit zpětným lomítkem (\
) a Bash si jich poté nevšímá.
Zbývá vyřešit již jen situaci, kdy potřebujeme zapsat zpětné lomítko. V
tu chvíli ho odescapujeme a zapíšeme jednoduše 2 za sebou:
Kromě dolaru, různých uvozovek a mezer můžeme pomocí escapování zapsat i několik speciálních znaků:
\n |
Zalomení řádku. U textových souborů z Windows bude znak následován
ještě znakem \r . |
\t |
Tabulátor |
\\ |
Zpětné lomítko |
\f |
Form feed přinutí tiskárnu, aby vysunula danou stránku |
\a |
Alert terminálu (pípnutí) |
V příští lekci, Linuxový terminál (Bash) - Správa uživatelů, se naučíme pracovat s nejdůležitějšími příkazy pro správu uživatelů v Linuxu.