Obsah
Proč pracovat s příkazovou řádkou? Grafická prostředí a grafické aplikace mohou být příjemné a pohodlné, ovšem jen do té doby, dokud po nich chceme to, co programátory napadlo. Ve chvíli, kdy chceme něco extra, může se z příjemného pobytu v grafickém prostředí stát noční můra. To, co bychom v příkazové řádce vyřešili jedním vhodně sestaveným příkazem, můžeme v grafickém prostředí realizovat hodiny a hodiny.
Práce s příkazovou řádkou není sice úplně jednoduchá záležitost, ale jakmile se s ní naučíte pracovat, získáte opravdu mocného spojence. Uživatelé bez příslušných znalostí (nebo uživatelé neunixových operačních systémů) vás pak možná začnou považovat za opravdového mága.
Co všechno lze s pomocí příkazové řádky realizovat? Mnohé. Potřebujete zjistit, co za objemné soubory máte ve svém domovském adresáři? Tento příkaz vypíše všechny soubory větší než 100MB ve vašem domovském adresáři.
find ~/ -size +100M
Máte jpg soubory rozeseté v komplexní adresářové struktuře a chcete je všechny přesunout do jednoho adresáře? Můžete to dělat ručně, nebo použít příkaz:
find ~/ -name "*.jpg" -type f -exec mv {} /mnt/skladiste \;Chcete si zálohovat MBR na disku sda?
dd if=/dev/sda of=zaloha.mbr bs=512 count=1
Chcete bezpečně vymazat pevný disk sda, aby ste si mohli být jisti, že z něj nepůjdou obnovit vaše soukormá data?
shred /dev/sda
Naučit se efektivně využívat příkazovou řádku není jednoduché, navíc je třeba to vhodně spojit se znalostí fungování počítače a vnitřností GNU/Linuxu. Kupříkladu, výše zmíněný příklad se zálohou MBR vyžaduje znalost symboliky zařízení v GNU/Linuxu a unixové filosofie vše je soubor. Celý pevný disk je v našem příkladu reprezentován souborem /dev/sda, se kterým lze zacházet jako se kterýmkoliv jiným souborem, tj. číst z něj, zapisovat do něj, apod. Víme-li tohle a víme-li, že MBR se nachází v prvních 512 bytech pevného disku, můžeme použít program dd, který nám obsah MBR zapíše do souboru.
Jistě, na řadu úkonů jsou k dispozici různé speciální uživatelsky přívětivé nástroje (zejména pro systém Windows je typická existence tisíců takových jednoúčelových nástrojů, zpravidla proprietárních, komerčních a nezřídka s porcí malware navíc). Nepochybně existují nějaká uživatelsky přívětivá řešení pro zálohu MBR či bezpečné vymazání pevného disku, nevyžadující znalost příkazové řádky ani fungování počítače. Nikdy však nebudou existovat nástroje na splnění všech vašich požadavků, zejména těch komplexních.
Výhoda schopnosti efektivně využívat příkazovou řádku tkví v tom, že jste schopni sestavit jednoduché i komplexní řešení vašich požadavků, a to přesně na míru. Do této schopnosti je však třeba investovat nějaký čas.
Rozlišujme mezi textovým režimem, terminálem, příkazovou řádkou a interpretem příkazové řádky. Textovým režimem označuji implicitní prostředí GNU/Linuxu mimo grafické rozhraní, tj. mimo X server. Přívětivé distribuce se obvykle snaží textový řežim zakrýt, avšak i když systém nastartuje do grafického rozhraní, aniž byste zahlédli textový režim, můžete se do něj snadno přepnout prostřednictvím Ctrl+Alt a některé z funkčních kláves (zpravidla F1 až F6). Pomocí této klávesové zkratky se dostanete z grafického prostředí do textového režimu, na některý z virtuálních terminálů (podle toho, jakou funkční klávesu jste použili). V textovém režimu se mezi virtuálními terminály přepínáte pomocí Altu a funkční klávesy. Na jednom virtuálním terminálu běží grafické rozhraní (zpravidla na sedmém). Přepnete-li se tedy pomocí Alt+F7 na sedmý terminál, ocitnete se zpět v grafickém prostředí.
Terminálem [20] budeme označovat program, prostřednictvím kterého je možné pracovat s příkazovou řádkou. V grafickém prostředí máte k dispozici celou řadu terminálů, třeba Konsole nebo gnome-terminal. Tyto programy přirozeně podporují ovládání myší, což je dobré zejména pro označování a kopírování textu.
Interpret příkazové řádky nebo shell je program, který interpretuje vaše příkazy a vykonává je. V GNU/Linuxu máte na výběr z mnoha shellů, přičemž výchozí je bash. Na něj se zaměříme.
Nuže, nyní již víme, jak se dostat k příkazové řádce. Buď přihlášením na některý z virtuálních terminálů v textovém režimu nebo prostřednictvím nějakého terminálu v grafickém prostředí.
Nejprve bych rád probral několik záležitostí, které značně usnadňují práci. Tou první je program s názvem Midnight Commander, jehož instalaci doporučuji provést, i když pobyt v příkazové řádce neplánujete. Midnight Commander, který se spouští příkazem mc, je diskový manažer podobný Norton Commanderu (nebo Total Commanderu, chcete-li). Mnoho funkcí, které budeme realizovat pomocí příkazů, lze provést pomocí tohoto programu mnohem snadněji.
Pokud budete pracovat v shellu, hodí se vědět o historii příkazů, ve které se můžete pohybovat pomocí šipek nahoru a dolů. Můžete tak listovat mezi dříve spouštěnými příkazy a ty upravovat. Přirozeně, když fungují šipky nahoru a dolů, fungují i šipky vlevo a vpravo, pomocí kterých se můžete pohybovat v textu aktuálně zadávaného příkazu a libovolně jej upravovat. Samozřejmě fungují i klávesy jako Delete nebo Backspace.
Další podstatnou věcí, o které je dobré vědět, je vlastnost zvaná doplňování, v Bashi se realizuje pomocí tabulátoru. Když potřebujete doplnit jméno souboru nebo cestu k němu, můžete si tak značně pomoci. Zadáte prvních pár písmen a stisknete tabulátor. Bash doplní zbytek. V případě, že vámi zadnému fragmentu odpovídá více souborů, opakovaný stisk tabulátoru je zobrazí. Po doplnění dostatečného počtu znaků a stisknutí tabulátoru se doplní konkrétní soubor.
Jak víme, v GNU/Linuxu je vše uloženo v jisté hierarchické adresářové struktuře, která začíná kořenovým adresářem a rozvětvuje se do jednotlivých podadresářů. Pokud se dostaneme k příkazové řádce, zpravidla se ocitneme ve svém domovském adresáři. První věcí, kterou se naučíme, je pohyb po adresářové struktuře.
Abychom mohli vyrazit na průzkum, musíme si s sebou vzít příslušné vybavení, modul GPS umožňující zjistit kdekoliv naši pozici (příkaz pwd), svítilnu k prohledávání momentálního okolí (příkaz ls) a dopravní prostředek (příkaz cd). Posledním předpokladem je schopnost navigace, tedy povědomí o adresářové struktuře a znalost tzv. absolutních a relativních cest.
To není nic komplikovaného. Kupříkladu, mějme soubor /var/log/messages (povšimněte si, že jednotlivé položky v cestě se oddělují lomítkem). Tato cesta začíná lomítkem (kořenovým adresářem), a proto se jí říká absolutní cesta. Pokud se však nacházíme v adresáři /var, je relativní cesta k tomuto souboru log/messages. Relativní cesta je cesta k souboru z aktuálního adresáře. Jsme-li tedy ve /var, nemusíme vypisovat absolutní cestu, můžeme použít cestu relativní.
Každý adresář má vždy alespoň dvě položky, odkaz sám na sebe (tečku) a odkaz na předchozí adresář (dvě tečky). Pokud se tedy nacházíme v adresáři /var/tmp, můžeme se k příslušnému souboru dostat přes odkaz na předchozí adresář, tedy takto - ../log/messages. Pokud bychom se nacházeli v adresáři /var/tmp/mike, měla by relativní cesta o jeden skok na předchozí adresář více - ../../log/messages.
Nyní se již můžeme pustit do vlastního průzkumu. Začneme tím, že zjistíme, kde jsme:
[michal@griffon ~]$ pwd home/michal
Jak vidíme, nacházíme se v adresáři /home/michal. Nyní se rozhlédneme:
[michal@griffon ~]$ ls linuxbook.xml Desktop
Teď už víme, že se v našem domovském adresáři nacházejí tyto položky. A na závěr se necháme přepravit do adresáře /tmp prostřednictvím relativní cesty:
[michal@griffon ~]$ cd ../../tmp
Přirozeně jsme mohli použít absolutní cestu, což by bylo i rychlejší:
[michal@griffon ~]$ cd /tmp
Program ls má některé zajímavé parametry, které nám umožní získat více informací. Volby unixových programů začínají vždy pomlčkou a mívají dvě formy, krátkou (např. -a) a dlouhou (např. --all-files). Tyto formy jsou zaměnitelné, použijte tu, která se vám lépe píše nebo pamatuje. Volby mohou mít i parametry, které jsou u krátké formy zpravidla specifikovány po jedné mezeře (např. -f soubor.txt, zatímco u dlouhé mohou být odděleny rovnítkem (např. --file=soubor.txt. Různé programy mají různé parametry a volby, o kterých se dozvíte v manuálových stránkách (příkaz man). Parametry a volby se oddělují mezerou. Názorněji to uvidíme na příkladech.
Parametrem programu ls je adresář, jehož obsah chcete vypsat. Pokud jej nespecifikujeme, vypíše se aktuální adresář. Pokud bychom tedy chtěli vypsat obsah adresáře /bin, zapsali bychom:
[michal@griffon ~]$ ls /bin
Tou nejpoužívanější volbou pro program ls je -l, která způsobí, že se vše vypíše v tzv. dlouhém formátu, kde získáte přehled o vlastníkovi a skupině příslušné danému souboru, jeho velikost a přístupová práva. Vyzkoušejme si to:
[michal@griffon ~]$ ls -l drwx------ 16 michal users 4096 2007-10-05 22:03 Desktop -rw-r--r-- 1 michal users 12578 2007-10-05 10:22 linuxbook.xml
Jak vidíme, ve výpisu máme k dispozici u jednotlivých položek přístupová práva, jméno vlastníka a skupiny, velikost, datum a čas poslední změny. Vidíme i typ jednotlivých položek (první znak na řádce), u položky Desktop vidíme, že se jedná o adresář (d jako directory). Normální soubor je označen pomlčkou, b by označovalo blokové zařízení, c znakové zařízení a l symbolický link.
Poslední důležitou volbu, kterou proberu, je -a. Tato volba zařídí vypsání všech souborů, i skrytých (tj. soubory začínající tečkou). Jednotlivé volby (resp. pouze ty, které neočekávají parametr) lze v případě ls a řady dalších unixových utilit kupit za jedinou pomlčku, takto:
[michal@griffon ~]$ ls -la
Jednotlivé volby jde samozřejmě rozepsat:
[michal@griffon ~]$ ls -l -a
To je ale zbytečná práce navíc, když to jde výše uvedeným způsobem.
V unixových systémech se typ souboru determinuje jinak než pomocí přípon, jak je tomu v některých jiných systémech. Soubory mají pouze jméno, přičemž přípona je jeho součástí, pokud je. Samozřejmě být nemusí. Typ souboru můžete zjistit pomocí příkazu file:
[michal@griffon ~]$ file linuxbook.xml linuxbook.xml: XML 1.0 document text
Podrobnější informace k určitému souboru můžete zjistit pomocí příkazu stat:
[michal@griffon ~]$ stat linuxbook.xml File: `linuxbook.xml' Size: 281722 Blocks: 560 IO Block: 4096 regular file Device: fe02h/65026d Inode: 2387440 Links: 1 Access: (0666/-rw-rw-rw-) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2007-10-16 20:02:57.000000000 +0200 Modify: 2007-10-16 20:02:57.000000000 +0200 Change: 2007-10-16 20:02:57.000000000 +0200
Pokud se jedná o textový soubor, budeme jej pravděpodobně chtít prohlédnout. Můžeme tak učinit příkazem cat, který slouží ke spojování obsahu více souborů, nebo lépe, a sice příkazem more, který zobrazí příslušný soubor tak, že jeho výpis neprobleskne obrazovkou, nebo ještě lépe, pomocí příkazu less, kde můžeme souborem pohodlně listovat či dokonce vyhledávat.
Less se ovládá následovně. Šipkami nebo pomocí Page Up a Page Down se pohybujeme v textu, výraz k vyhledání zadáváme pomocí lomítka, na další výskyt hledaného výrazu přejdeme pomocí klávesy n a prohlížení ukončíme klávesou q. Tento program bývá také využíván k prohlížení manuálových stránek prostřednictvím programu man.
Jelikož v GNU/Linuxu je nastavení uložené v konfiguračních souborech, což jsou obyčejné textové soubory, lze předpokládat, že se vám bude velice hodit znalost textových editorů pro příkazovou řádku. Mezi editory patří vi, emacs, nano, pico či mcedit, který, jak název napovídá, je součástí dříve zmiňovaného Midnight Commanderu.
Editory vi a emacs bývají pro začátečníky obtížné, zejména vi je pověstný tím, že mnozí neznalí ani nenajdou způsob, jak jej ukončit. Ostatní výše zmíněné editory se začátečníkům ovládají snadněji, a proto mohu jen doporučit si některý z nich opatřit, pokud jej nainstalovaný nemáte.
Pro strýčka příhodu jsem samozřejmě připravil rychlokurz používání editoru vi, který je ve většině unixových systémů a linuxových distribucích.
Editor Vi má několik režimů práce. Po spuštění se ocitnete v tzv. normálním režimu. Do něj se kdykoliv dostanete stisknutím klávesy Esc dvakrát. V normálním režimu sice nemůžete editovat text, ale můžete se po textu pohybovat, buď pomocí šipek, nebo pomocí kláves h (vlevo), j (dolů), k (nahoru), l (vpravo).
Z normálního režimu se můžete dostat do příkazového režimu pomocí dvojtečky. Příkazový režim je důležitý, neboť pomocí něj můžete editor opustit či soubor uložit (či obojí). Vi se ukončuje pomocí příkazu q, soubor se ukládá pomocí příkazu w. Uložit soubor a ukončit editor můžete pomocí příkazu wq. Pokud jste provedli nějaké změny a chcete editor ukončit bez uložení změn, Vi vás nepustí. Musíte mu explicitně říci, že se má provést daný příkaz bez ohledu na cokoliv dalšího, což provedete přidáním vykřičníku. Příkaz pro ukončení editoru bez uložení změn je tedy q!.
Do editačního režimu se dostanete pomocí klávesy Insert nebo i z normálního režimu.
Ještě před tím, než budeme pokračovat, měli bychom si vysvětlit zástupné znaky, speciální znaky a expanzi. Pokud bychom měli soubor s názvem nejaky text.txt a chtěli ho zobrazit pomocí programu less a zapsali následující příkaz, došlo by k něčemu neočekávanému:
less nejaky text.txt nejaky: není souborem ani adresářem text.txt: není souborem ani adresářem
Problém je ve speciálním znaku, kterým je v tomto případě mezera. Slouží jako oddělovač parametrů, takže náš program less interpretoval příslušný soubor jako dva soubory, které samozřejmě neexistují, a less je tedy není schopen zobrazit.
Mezi speciální znaky patří kromě mezery křížek (označuje komentář), zástupné znaky (hvězdička, otazník, hranaté závorky, tilda), vykřičník (negátor výrazu), zpětné lomítko (neutralizuje jeden bezprostředně následující speciální znak), uvozovky (neutralizují speciální znaky v textu mezi uvozovkami), středník (odděluje více příkazů na jednom řádku), lomítko (oddělovač prvků cesty), špičaté (složené) závorky (oddělují blok příkazů a jsou prostředkem expanze), kulaté závorky (oddělují skupinu příkazů), většítko a menšítko (přesměrování výstupu a vstupu), roura, paragraf (spustí příkaz na pozadí, znak dolaru (uvozuje proměnnou) a některé další.
Máme dvě možnosti. Buď neutralizujeme význam speciálního znaku (mezery) pomocí zpětného lomítka, nebo jméno souboru uzavřeme do uvozovek. Obojí bude fungovat:
less nejaky\ text.txt
less "nejaky text.txt"
Pokud bychom v názvu souboru měli samotné uvozovky, mohli bychom jejich vliv neutralizovat buď pomocí zpětného lomítka, nebo pomocí druhých uvozovek, takto:
less 'soubor s "textem".txt'
less soubor\ s\ \"textem\".txt
Pokud bychom měli soubor se zpětným lomítkem v názvu, zapsali bychom dvě zpětná lomítka za sebou, což by Bash interpretoval jako jedno normální zpětné lomítko bez speciálního významu.
Pokud chceme nějakému příkazu předat více než jeden soubor, můžeme použít zástupné znaky, abychom je všechny nemuseli explicitně specifikovat. Řekněme, že chceme prolistovat všechny soubory začínající na ukol a končící na txt. V tom případě můžeme použít speciální znak v podobě hvězdičky, která zastupuje libovolný počet znaků. Výsledný příkaz tedy bude vypadat takto:
less ukol*txt
Dalším zástupným znakem je otazník, který zastupuje právě jeden libovolný znak. Pokud tedy chceme prolistovat všechny soubory, které začínají jedním libovolným znakem a pokračují _ukol.txt, provedeme následující příkaz:
less ?_ukol.txt
Pomocí hranatých závorek můžeme specifikovat, které znaky se smí na daném místě použít. Následující příkaz tedy zobrazí soubory a_ukol.txt a b_ukol.txt, pokud existují:
ls [ab]_ukol.txt
Můžeme samozřejmě specifikovat i rozsahy znaků a dokonce daný výraz negovat. Zkusíme tedy zobrazit všechny soubory začínající jedním velkým písmenem nebo jedním číslem:
ls [A-Z0-9]*
Nyní zobrazíme všechny soubory, které nezačínají číslem:
ls [!0-9]*
Měli bychom si ještě ozřejmit jednu důležitou věc. Pokud použijete jakýkoliv speciální znak jako parametr nějakého příkazu, Bash interpretuje jeho význam a příkazu předá výsledek. Ujasněme si to na příkladu. Mějme adresář s následujícími soubory:
abc_ukol.txt a_ukol.txt b_ukol.txt c_ukol.txt 5_ukol.txt
Nyní chceme zobrazit obsah všech souborů začínající na a, takže použijeme příkaz:
ls a*
Bash nejprve vyřeší speciální znaky ve výrazu a programu ls předá výsledek. Program ls tedy obdrží seznam souborů v aktuálním adresáři, které začínají na a. Je to úplně stejné, jako kdybychom zapsali:
ls abc_ukol.txt a_ukol.txt
Speciální znaky a jejich význam si můžeme otestovat pomocí "ozvěny" v podobě programu echo. Ten vypíše na obrazovku všechno, co jsme mu předali jako parametry. Takže pokud bychom v tomto adresáři zapsali:
echo a*
Pak bychom obdrželi:
abc_ukol.txt a_ukol.txt
Program echo má ještě jeden zajímavý parametr, a tím je -n. Použití tohoto parametru způsobí, že echo neukončí výpis znakem konce řádku. To se nám bude hodit později.
Jiným zajímavým zástupným znakem je tilda (~), která supluje cestu k vašemu domovskému adresáři. Pokud se nacházíte někde úplně mimo, můžete se do svého domovského adresáře snadno navrátit příkazem:
cd ~
Bash si pamatuje, kde jste byli naposled a není problém se vrátit do předchozího adresáře:
cd -
Tím bychom mohli probírání zástupných znaků ukončit.
Opět připomínám, že mnoho operací se dá snado provést pomocí Midnight Commanderu. Nicméně někdy se určitě hodí vědět, jak běžné operace se soubory provádět "ručně". A pokud nahlédnete do manuálových stránek příslušných příkazů, možná objevíte i nové netušené možnosti, jak snadno provádět jisté náročnější operace.
Příkazy, které si představíme, jsou cp (kopírování), mv (přesun), rm (mazání souborů), rmdir (mazání adresářů), touch (vytvoření prázdného souboru), mkdir (vytvoření adresáře) a ln (vytvoření linku).
Zkusme si na jednoduchém příkladu ukázat základní práci se soubory:
[michal@griffon ~]$ ls [michal@griffon ~]$ touch soubor [michal@griffon ~]$ mkdir Adresar [michal@griffon ~]$ ls Adresar soubor [michal@griffon ~]$ cp soubor Adresar [michal@griffon ~]$ ls Adresar soubor [michal@griffon ~]$ ls Adresar soubor [michal@griffon ~]$ rm soubor [michal@griffon ~]$ ls Adresar [michal@griffon ~]$ mv Adresar/soubor . [michal@griffon ~]$ ls Adresar [michal@griffon ~]$ ls Adresar soubor [michal@griffon ~]$ rmdir Adresar [michal@griffon ~]$ ls soubor
Přibližme si teď jednotlivé příkazy podrobněji.
Základní syntax příkazu cp jsme již probrali:
cp soubor adresář
Souborů může být samozřejmě více:
cp soubor1 soubor2 soubor3 adresář
Můžeme zkopírovat jeden soubor do druhého (tím přepíšeme jeho obsah):
cp soubor1 soubor2
Můžeme zkopírovat ale i celý adresář včetně všech podadresářů a souborů, které obsahuje. K tomu použijeme volbu -R:
cp -R adresář1 adresář2
O dalších možnostech programu cp se dozvíte pročtením jeho manuálové stránky.
Abychom si demonstrovali jeden zástupný znak, zkusíme zkopírovat nějaký soubor do aktuálního adresáře:
cp /var/tmp/soubor .
Tečka je odkaz na aktuální adresář.
Program mv slouží k provádění přesunů nebo přejmenování. Má jasnou syntax:
mv zdroj1 zdroj2 zdroj3 cíl
Pokud specifikujete pouze jeden zdroj a zadaný cíl neexistuje, provede se přejmenování (platí samozřejmě pro soubory i adresáře):
mv staré_jméno nové_jméno
Pokud je cíl soubor, bude přepsán obsahem zdrojového souboru:
mv soubor1 soubor2
Je-li cílem adresář, všechny zdrojové soubory či adresáře se do něj přesunou:
mv soubor1 adresář1 cílový_adresář
Program rm slouží k mazání. Bez dalších parametrů maže pouze soubory:
rm soubor1 soubor2
Pokud chceme vymazat adresář i se všemi jeho podadresáři, použijeme parametr -r:
rm -r adresář_k_vymazání
S programem rm a jeho volbou -r lze napáchat mnoho škody. Pokud chceme vymazat adresář /tmp/práce, ale překlepneme se třeba takto:
rm -r / tmp/práce
Začně program rm mazat celý adresářový strom, a až skončí, zkusí smazat tmp/práce. Z tohoto důvodu si dávejte veliký pozor, budete-li mít oprávnění roota, protože tímto způsobem si spolehlivě zničíte celý systém včetně všech dat.
Program mkdir umí vytvořit adresář:
mkdir nový_adresář
Program touch se "dotkne" specifikovaného souboru. Pokud tento soubor existuje, upraví se mu čas poslední změny a přístupu na aktuální čas. Pokud neexistuje, bude vytvořen s nulovým obsahem:
touch soubor
Program ln slouží k vytváření symbolických nebo pevných odkazů. Následující příkaz vytvoří symbolický odkaz s názvem odkaz, který bude ukazovat na soubor data:
ln -s data odkaz
Pokud bychom chtěli vytvořit pevný odkaz, vynecháme volbu -s:
ln data pevný_odkaz
Pevný odkaz je de facto další jméno pro daný soubor. Podmínkou jeho vytvoření je, že se zdrojový soubor i budoucí odkaz nachází na stejném souborovém systému. Po vytvoření pevného odkazu není mezi zdrojem a obrazem žádný rozdíl, obě jména ukazují na jeden a ten samý soubor. Vymazat tedy můžete kterýkoliv. Po vymazání posledního jména ukazujícího na daný soubor bude tento soubor vymazán. Pevných odkazů může být samozřejmě více.
Souborový systém realizuje tuto záležitost jednoduše. Po vytvoření pevného odkazu se zvýší číslo označující počet odkazů na daný soubor (po vytvoření souboru má příslušný soubor jeden odkaz). Ve chvíli, kdy toto číslo klesne na nulu, soubor se opravdu vymaže.
Pokud potřebujete nějaký soubor najít, nepochybně se vám hodí znát příkaz find a locate. Příkaz locate prohledává databázi, která se aktualizuje zpravidla jednou denně. V této databázi jsou indexovány jednotlivé soubory. Výhodou tohoto postupu je, že vyhledávání je velice rychlé (prohledává se databáze a nikoliv vlastní adresářový strom). Nevýhodou je neaktuálnost. Použití programu je velice jednoduché:
locate vyraz
Můžete samozřejmě použít příslušné zástupné znaky. Pokud hledáte pouze umístění nějakého spustitelného programu, pomůže vám which:
which bash
Program find prohledává zadanou adresářovou strukturu přímo, bez pomoci nějaké databáze. Je to velmi komplexní program s řadou voleb. My si ukážeme opět jen to nejběžnější použití:
find /tmp -name "michal*.txt"
Takto bychom hledali soubor s názvem michal[cokoliv].txt v adresáři /tmp. Hledat můžeme ale i pomocí jiných kritérií:
find /tmp -type d
Tento příkaz pro změnu hledá soubory podle typu. Typ d označuje adresář. Příkaz tedy vypíše všechny adresáře v /tmp.
Pomocí find lze hledat soubory podle nejrůznějších kritérií včetně doby založení či poslední změny. Více informací viz manuálová stránka programu find:
man find
Existují dva podstatné prostředky výstupu, stdout (standardní výstup) a stderr (chybový výstup). Smysl tohoto dělení je v tom, že lze kterýkoliv z nich (nebo oba) přesměrovat jinam. Pro vstup je určen stdin (standardní vstup). Vstup a výstup se běžně tiskne na obrazovku, ale lze jej přesměrovat jinam pomocí většítka a menšítka. Jak to všechno funguje v praxi si nyní ukážeme.
Řekněme, že bychom chtěli výpis obsahu adresáře uložit do souboru. V tom případě bychom rádi přesměrovali standardní výstup do souboru, což provedeme takto:
[michal@griffon ~]$ ls -l > vypis.txt
Pokud použijeme dvě většítka za sebou, soubor vypis.txt se nepřepíše, výpis se připojí na konec souboru:
[michal@griffon ~]$ ls -l >> vypis.txt
Stejně jako výstup lze přesměrovat i vstup, a příslušnému programu je tak možné poslat data ke zpracování z nějakého souboru (místo z klávesnice). Zkusme třeba tohle:
[michal@griffon ~]$ sort < vypis.txt
Program sort umí setřídit řádky podle určitých kritérií. Tento příkaz způsobil, že program sort zpracoval řádky v souboru vypis.txt a setřídil je výchozím způsobem.
Vstup i výstup lze přesměrovat najednou:
[michal@griffon ~]$ sort < vypis.txt > setrideno.txt
Tímto příkazem jsme setřídili řádky souboru vypis.txt a výsledek uložili do souboru setrideno.txt.
Dosud jsme pracovali pouze se standardním vstupem a výstupem, ale co chybový výstup (stderr)? Ten můžeme přesměrovat takto:
[michal@griffon ~]$ cp work/* /tmp 2&> chyby.txt
Tento příkaz zkopíruje obsah podadresáře work do adresáře /tmp a veškeré chybové hlášky uloží do souboru chyby.txt.
Nyní se dostáváme k tmelu, který umožňuje propojit jednotlivé unixové utility do složitějších funkčních celků. Roura je de facto pojítkem mezi dvěma programy v tom smyslu, že standardní výstup jednoho přesměruje na standardní vstup druhého. Nejtypičtější a nejjednodušší příklad by byl použití programu less, abychom si mohli prohlédnout delší výpis programu ls. To by se realizovalo takto:
[michal@griffon ~]$ ls -l | less
Známe-li z dřívějška program sort, můžeme jej napojit na výpis programu du, který vypisuje velikosti souborů (a adresářů). S vhodnými parametry získáme setříděný výpis (od největšího po nejmenší) velikosti domovských adresářů uživatelů:
du -s /home/* | sort -nr
Ještě jednou, co tedy roura způsobí? Způsobí to, že výpis programu du (tedy jeho standardní výstup) pošle (na standardní vstup) programu sort. Ten příslušný výpis zpracuje (setřídí) a pošle opět na standardní výstup, v tomto případě už na naši obrazovku.
Zkusme další příklad. Program head nebo tail nám poslouží, abychom z nějakého výpisu získali začátek nebo konec. V tomto případě bychom si mohli nechat vypsat pouze pět adresářů s největším obsahem:
du -s /home/* | sort -nr | head -n 5
Nyní zkusme nějaký komplexnější příkaz:
dd if=/dev/hda | gzip -c | ssh mike@base "dd of=~/dump"
Tenhle příkaz umožňuje poslat obsah blokového zařízení hda přes síť zabezpečeným (šifrovaným) kanálem a uložit jeho obsah do souboru dump v domovském adresáři uživatele mike na vzdáleném počítači base. Před tím, než se data pošlou přes síť se v tomto případě zkomprimují pomocí programu gzip.
Tímto příkladem se snažím ukázat, jak je v unixových systémech všechno pěkně propojeno. Jednotlivé unixové nástroje dělají jen jednu věc, ale dělají ji dobře. Tyto nástroje lze pak propojit prostřednictvím příkazové řádky a kombinovat do různých funkčních celků. V unixových systémech také platí, že všechno je soubor, tedy i pevný disk[21]. Unixové nástroje umí velmi dobře pracovat se soubory. Dvě vlastnosti unixových systémů, které se vhodně doplňují a umožňují "snadno" realizovat to, k čemu je v jiných operačních systémech potřeba speciální (a zpravidla komerční) software.
Filtry jsou jednoúčelové programy, které nějakým způsobem upravují data ze standardního vstupu a upravená data posílají na standardní výstup. Mohou je třídit, upravovat nebo propouštět jen určité řádky nebo vzory.
Tabulka 7.1. Nejtypičtější filtry
| Filtr | Činnost |
|---|---|
sort | setřídí řádky podle zadaných kritérií |
uniq | ze setříděných řádek odstraní duplicity |
grep | propouští pouze řádky obsahující určitý vzor či výraz |
head | zachytí pouze několik prvních řádků výstupu |
tail | zachytí pouze několik posledních řádků výstupu |
tr | "překládá" znaky; může třeba provést konverzi velkých písmen na malá, apod. |
sed | tzv. "stream editor", umožňuje různě upravovat jím procházející text |
awk | programovací jazyk zaměřený na filtrování |
cut | umožňuje "vyříznout" kusy řádek |
wc | vrací počet slov (nebo počet řádek, použijeme-li parametr -l) |
Pokud bychom měli na výstupu nějakého programu řadu duplicitních řádek, hodí se nám program uniq, který duplicity odstraní. Tomuto programu musíme ale nejprve pomoci a duplicitní řádky dát k sobě. K tomu použijeme nám známý program sort:
ps auh | cut -f 1 -d\ | sort | uniq
Tento příkaz vypíše všechny uživatele, pod jejichž právy běží některé procesy. Jako základ jsme použili program ps k vypsání všech procesů. Z jeho výstupu se nám hodí pouze první slovo na každé řádce. To představuje uživatele, pod jehož právy běží každý proces. Pomocí filtru cut jsme "vyřízli" pouze první pole, jako oddělovač jsme specifikovali mezeru. Všimněte si zpětného lomítka, který neutralizoval vliv mezery jako oddělovače parametrů. Následně jsme výpis setřídili programem sort a odstranili duplicity pomocí programu uniq.
Použití programu cut je vhodné použít tam, kde jsou jasně dané oddělovací znaky. Třeba v souboru /etc/passwd slouží jako oddělovač dvojtečka. Můžeme tedy snadno získat výchozí interpret příkazové řádky (shell) uživatele michal:
grep michal /etc/passwd | cut -f 7 -d:
Naopak tam, kde je výpis nějakým způsobem formátovaný a nelze se tedy spolehnout na oddělovací znaky, je vhodnější využít program awk následujícím způsobem:
ps aux | awk '{ print $2 }'Tento příkaz vypíše všechny PID běžících procesů. Ty se nachází ve druhém sloupci výpisu programu ps, proto ta dvojka. Kdybychom chtěli jiný sloupec, nahradili bychom toto číslo adekvátním pořadovým číslem zvoleného sloupce.
Dlužno dodat, že program ps umožňuje velmi přesně specifikovat výstupní formát svého výpisu, a proto není tento trik vyloženě nutné znát. Na stranu druhou, je snadnější použít tento zápis, pokud si ho pamatujete, než pátrat v manuálové stránce programu ps, jak vhodně formátovat jeho výstup, aby se na něj dal použít program cut.
Program sed umožňuje provádět sofistikovanější úpravy filtrovaného textu. Asi nejznámější je konstrukce pro nahrazení nějakého řetězce jiným:
echo "Jdeme tam." | sed s/Jdeme/Nejdeme/
To je samozřejmě velmi primitivní příklad. Můžeme zkusit něco trošku složitějšího:
grep michal /etc/passwd | sed s/bash/zsh/
Tento příkaz upraví řádku se záznamem uživatele michal v /etc/passwd tak, že změní jeho výchozí shell z Bashe na zsh.
K programům awk a sed a jejich použití se dají najít i celé knihy, které do podrobna rozebírají jejich možnosti. Ze své praxe však nejčastěji používám výše uvedené konstrukce.
Program tr umožňuje nahradit nějakou skupinu znaků jinou skupinou. Může třeba převést všechna malá písmena v nějakém výpisu na velká:
[michal@griffon ~]$ echo "Ahoj" | tr [a-z] [A-Z] AHOJ
Vpomeňme na zástupné znaky a význam hranatých závorek. Je možné provádět různé "překlady", ale to už nechám na vaší fantazii.
Program wc (zkrácenina od "word count") umí počítat slova nebo řádky v nějakém výpisu. Takže můžeme třeba velice snadno zjistit počet uživatelů v systému:
wc -l /etc/passwd
A ani jsme nemuseli použít žádnou rouru. Program wc ale samozřejmě umí pracovat i jako součást roury:
grep bash /etc/passwd | wc -l
Jak správně tušíte, příkaz vypíše počet uživatelů, kteří mají jako výchozí shell nastavený bash.
Někdy se dostanete do situace, kdy budete chtít jako parametr zadat výstup nějakého příkazu. Kupříkladu, budete chtít zabít všechny procesy uživatele brian. Program ps vám poskytne potřebné informace o PID jednotlivých procesů, které pak budete chtít předat programu kill. Ten je však očekává jako parametr. Co s tím?
kill -9 `ps au | grep "brian" | awk '{print $1}'`To, co uzavřete mezi znaky ` se provede nejdříve a jejich obsah se nahradí za výstup příslušného výrazu. V tomto případě se tedy nejprve provede příkaz ps, od něhož získáme příslušná PID, která se pak vloží na místo, kde je očekává program kill. Tento zápis je plně ekvivalentní s tímto:
kill -9 $(ps au | grep "brian" | awk '{print $1}')Jak už víme z dřívějška, grep umí různě filtrovat řádky podle vzorů. A tím vzorem může být kromě slova i regulární výraz. Pomocí něj můžeme velmi přesně specifikovat to, co se má filtrovat.
Předpokládám, že zástupné znaky již znáte, včetně možnosti na určitém místě specifikovat rozsah znaků, které se mají vybrat, pomocí hranatých závorek. A třeba právě to je také regulární výraz.
Něco takového už by nám mělo být jasné:
[Aa]hoj
Tomuto výrazu vyhoví jak ahoj, tak Ahoj. V hranatých závorkách jsme specifikovali, že na prvním místě může být velké nebo malé A. V regulárních výrazech máme ale k dispozici další zástupné a speciální znaky (viz tabulka). Cokoliv mimo těchto zástupných znaků bude interpretováno jako text, který se musí vyskytovat v příslušném řetězci, aby ten odpovídal regulárnímu výrazu.
Tabulka 7.2. Významy speciálních znaků v regulárních výrazech
| Znak(y) | Význam |
|---|---|
. | tečka zastupuje jeden libovolný znak |
[] | hranaté závorky zastupují jeden znak, který musí odpovídat některému ze znaků uvnitř hranatých závorek |
^ | začátek řádku |
$ | konec řádku |
? | předchozí znak je nepovinný a smí se nacházet v daném výrazu nejvýše jednou |
* | libovolný počet opakování předchozího znaku (včetně nulového opakování, tj. situaci, kdy se znak na daném místě nenachází) |
+ | předchozí znak se musí vyskytovat alespoň jednou nebo vícekrát |
{n} | předchozí znak se musí vyskytovat n krát |
{n,} | předchozí znak se musí vyskytovat n nebo více krát |
{,m} | předchozí znak se musí vyskytovat nejvýše m krát |
{n,m} | předchozí znak se musí vyskytovat nejméně n krát a nejvíce m krát |
| | roura je logickou spojkou nebo, tj. umožňuje specifikovat více regulárních výrazů, přičemž filtrovaný řetězec bude propuštěn, pokud vyhoví kterémukoliv z nich |
Jakkoliv složitě to vypadá, je to vlastně docela jednoduché. Podívejme se na několik příkladů, na kterých si vše objasníme. Začneme tímto výrazem:
^[A-Z]hoj$
Znaky ^ a $ označují začátek a konec řádku. Tento regulární výraz tedy propustí pouze ty řádky, které začínají jedním velkým písmenem, pokračují textem hoj a tím končí.
^[0-9A-Za-z]{5}$Tomuto regulárnímu výrazu odpoví jakákoliv řádka, na které je pouze pět znaků, a to z alfanumerické množiny (velká a malá písmena, čísla).
michal|jana
Tomuto regulárnímu výrazu odpoví jakýkoliv řetězec, ve kterém se nachází michal nebo jana. Znakem roury jsme spojili dva regulární výrazy do jednoho, kterému odpovídá jakýkoliv řetězec, který vyhovuje kterémukoliv z těchto dvou regulárních výrazů.
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}Tento regulární výraz propustí jakýkoliv řetězec obsahující IP adresu. Přesněji jakýkoliv řetězec, který obsahuje jedno až tři čísla, tečku (zpětným lomítkem jsme neutralizovali její vliv jako zástupný znak pro jeden libovolný znak), jedno až tři čísla, další tečku, jedno až tři čísla, tečku a jedno až tři čísla.
Dlužno dodat, že tomuto výrazu bude odpovídat i nesmyslná IP adresa jako třeba tato:
945.847.654.425
Pokračujme dál:
ah.*oj
Tento regulární výraz bude odpovídat všem řetězcům, kde se nachází ah, libovolný počet libovolných znaků a oj.
Regulární výrazy v grepu se zadávají malinko jinak, než jsme si ukázali. Respektive, abychom mohli pracovat s regulárními výrazy tak, jak jsme na ně zvyklí, museli bychom použít takovýto příkaz:
echo -e "miii\nmooo" | grep -E "mi{3}|mo{3}"Ten by pak vrátil následující:
miii mooo
Tohle si opět podrobně vysvětlíme. Volbou -e programu echo jsme povolili interpretaci speciálních znaků uvozených zpětným lomítkem. Takovým znakem je třeba \n, který se pak interpretuje jako odentrování (tj. znak nového řádku). Tento zápis tedy vytvoří dva řádky, jeden s obsahem miii a druhý s obsahem mooo.
Regulární výrazy jsou spojeny rourou, takže vyhoví obě řádky. Jedna vyhoví prvnímu výrazu, druhá druhému. Grepu jsme museli parametrem -E říci, aby daný výraz interpretoval jako rozšířený regulární výraz. To je takový, na který jsme si dosud zvykli. Bez tohoto parametru interpretuje grep (a také třeba sed a další programy) pouze "základní" regulární výrazy. To jsou takové, kde místo speciálních znaků regulárních výrazů použijete jejich ekvivalenty se zpětným lomítkem, jako byste chtěli neutralizovat jejich význam.
Výše zmíněný výraz bychom pro standardní grep tedy museli přepsat do této podoby:
mi\{3\}\|mo\{3\}Vypadá to sice hrozivě, ale pokud víte, že před každý ze speciálních znaků regulárních výrazů napíšete zpětné lomítko, není to až takový problém.
Unixové systémy jsou víceúlohové, a jako takové nabízejí prostředky, jak realizovat více úloh současně. Kupříkladu, pokud budeme chtít pustit nějaký časově náročný program, ale budeme chtít dále pracovat s příkazovou řádkou, prostě ho pustíme na pozadí:
dd if=/dev/urandom of=whitenoise &
Ampersand na konci příkazu způsobí, že se daný příkaz začne provádět na pozadí. Pokud už nějaký program běží a vy jej chcete přesunout na pozadí, jde to také, i když je to o něco komplikovanější. Stiskem Ctrl+Z průběh daného příkazu (programu) zastavíte. Tak se dostanete k příkazové řádce, ale v tuto chvíli ještě daná úloha na pozadí neběží. Je jen pozastavená. Jednotlivé úlohy si můžete nechat vypsat pomocí příkazu jobs.
Číslo u každé úlohy je poměrně důležité, protože vám umožní danou úlohu převést do pozadí nebo opět do popředí. Pokud má naše pozastavená úloha číslo jedna, provedeme toto:
bg 1
Teoreticky jsme nemuseli číslo specifikovat, neboť bez parametru se převede do pozadí naposledy pozastavená úloha. Ale pokud budete mít takových úloh více, tomuto se nevyhnete.
Kteroukoliv úlohu můžete převést opět do popředí pomocí příkazu fg:
fg 1
V tomto případě bychom na pozadí běžící (nebo pozastavenou) úlohu č. 1 převedli na popředí.
Práci s více shelly na jednom terminálu umožňuje velmi snadno program screen. Jeho výhodou je to, že po jeho ukončení zůstanou všechny úlohy a shelly běžet, takže se k rozdělané práci můžete snadno vrátit na jiném terminálu.
Velkou část příkazů pro správu systému jsem již probral v jiných kapitolách. Máme tu nicméně pár restů. Nejprve si řekneme, jak získat oprávnění uživatele root nebo jiného uživatele. Abychom se "stali" jiným uživatelem, použijeme program su s parametrem v podobě uživatelského jména toho, jehož oprávnění chceme získat:
su michal
Budeme vyzváni k zadání hesla uživatele michal a pokud jej zapíšeme správně, získáme veškerá jeho oprávnění.
Pokud na konec příkazu umístíme pomlčku, získáme nejenom práva příslušného uživatele, ale i příslušná nastavení, která se hodí zejména v případě uživatele root. Ten má totiž v proměnné PATH uloženy adresáře /sbin a /usr/sbin. Pokud bychom pouze získali oprávnění uživatele root bez této úpravy, budeme muset upravit proměnnou PATH nebo specifikovat cestu ke všem programům v těchto adresářích, budeme-li je chtít použít.
su -
Pokud použijeme program su bez parametru v podobě uživatele, zvolí se výchozí uživatel, kterým je root.
Programem su můžeme spustit třeba pouze jediný příkaz:
su -c "ifconfig eth0 10.0.0.1 netmask 255.255.255.0"
Tento příkaz provede změnu nastavení síťové karty eth0 na zmíněnou adresu a síťovou masku. K tomu je třeba oprávnění uživatele root, která získáme pomocí programu su.
Jiný mechanismus představuje program sudo, jehož nastavení je v /etc/sudoers. Tento program umožňuje získat příslušná oprávnění na jediný příkaz, avšak postačí k tomu naše heslo, tedy heslo uživatele. Sudo si navíc po zadání hesla pamatuje, že jste prověřená osoba a následné spuštění sudo už nebude vyžadovat žádné heslo. Pokud sudo nepoužijete během pěti minut, program opět zapomene, že jste prověřená osoba a o heslo požádá.
Příkladem použití může být třeba ekvivalent našeho příkazu výše:
sudo ifconfig eth0 10.0.0.1 netmask 255.255.255.0
V grafickém prostředí je vhodné pro spouštění "okenních" aplikací s jinými právy používat programy jako kdesu, gksu či gksudo.
Ke změně oprávnění uživatelů slouží příkazy chmod, chown a chgrp. První zmíněný slouží ke změně práv, druhý ke změně vlastníka, třetí ke změně skupiny. Vše se samozřejmě týká souborů (resp. adresářů). Používají se poměrně snadno:
chown michal soubor.txt
Tento příkaz změnil vlastníka souboru soubor.txt na uživatele michal. Pokud bychom chtěli změnit skupinu příslušného souboru na users, provedeme:
chgrp users soubor.txt
Obojí můžeme provést i rychleji, jedním příkazem:
chown michal:users soubor.txt
Změny oprávnění pomocí programu chmod můžeme zadávat různě. Můžeme použít oktální číselnou reprezentaci nebo můžeme použít symbolický zápis.
Pokud si vzpomínáte na zápis oprávnění rwxrwxrwx, tak tam se první tři práva týkají vlastníka souboru, další člena skupiny a třetí ostatních uživatelů, přičemž r označuje právo čtení (v případě adresáře právo zobrazit jeho obsah), w označuje právo zápisu (v případě adresáře právo vytváření a mazání souborů) a x právo spustit soubor (v případě adresáře právo se do něj přepnout).
Oktální číselná reprezentace vychází z osmičkové soustavy a tvoří ji tři čísla, kde první reprezentuje práva vlastníka, druhé skupiny a třetí ostatních uživatelů. Jednotlivým oprávněním jsou přiřazeny hodnoty (r=4, w=2, x=1), které se sčítají. Tudíž, práva rwxrw-r-- bude možné označit jako:
chmod 754 soubor.txt
Symbolický zápis pak rozeznává práva r, w, x, jak už je známe, a subjekty vlastník (u, user), skupina (g, group), ostatní (o, other) a všichni (a, all). Jednotlivá práva lze přidávat pomocí znaku +, odebírat pomocí znaku - a nastavovat pomocí znaku =. Následující příkaz tedy přiřadí všem subjektům možnost soubor číst:
chmod a+r soubor.txt
Následující příkaz přidá uživateli a skupině právo číst a zapisovat:
chmod ug+rw soubor.txt
Tento příkaz nastaví oprávnění příslušného souboru tak, že vlastníkovi nastaví právo číst a zapisovat, skupině pouze právo číst a ostatním uživatelům žádná práva nepřidělí:
chmod u=rw,g=r,o= soubor.txt
Jak vidíme, zápis pomocí čísel je poněkud rychlejší.
Jsou v zásadě dvě možnosti, jak se připojit k vzdálené příkazové řádce na jiném unixovém stroji. Tou první je hodně zastaralá a nebezpečná metoda - telnet. Telnet je nebezpečný v tom, že komunikace mezi počítači není šifrovaná, hesla putují v nezměněné podobě a kdokoliv, kdo by poslouchal na cestě, může velmi snadno k těmto informacím přijít. Naštěstí je tato metoda tak zastaralá, že se s ní velmi pravděpodobně nesetkáte.
Mnohem lepší metodou je použít SSH (Secured SHell). Na počítači, kam se chceme přihlásit, musí běžet SSH server (v prostředí GNU/Linuxu to bude velmi pravděpodobně OpenSSH) a firewall nesmí blokovat port 22, na kterém SSH běží.
SSH klient bývá běžně přítomný snad v drtivé většině linuxových distribucí, ne-li skoro ve všech. Jsou k dispozici i klienti pro Windows[22]. SSH klient má velice jednoduchou syntax:
ssh uzivatel@pocitac
Je možné použít i trošku delší variantu:
ssh -l uzivatel pocitac
Při prvním spuštění se nás klient zeptá, jestli akceptujeme identitu serveru danou otiskem (fingerprint) jeho veřejného klíče. Nebývá na škodu si jej ověřit. Klient pak při každém dalším přihlášení kontroluje identitu serveru a odmítne se přihlásit, pokud otisk nesouhlasí. Zabrání tak tzv. man in the middle útoku[23].
Po zadání hesla se dostaneme k příkazové řádce vzdáleného počítače a s vhodně nakonfigurovaným serverem můžeme spouštět i grafické aplikace. Takto můžeme velmi snadno spravovat počítač na dálku.
Součástí balení SSH klienta je i program scp, který umožňuje mezi počítači kopírovat soubory (pomocí SSH):
scp soubor uzivatel@server:/cilovy/adresar
Zápis je možné samozřejmě obrátit:
scp uzivatel@server:/zdrojovy/soubor.txt .
Přes SSH lze kopírovat i v pohodlí grafického prostředí. Zkuste třeba v Konqueroru nebo Krusaderu zapsat adresu:
fish://uzivatel@pocitac
K dispozici jsou i scp klienti pro Windows[24].
William Shotts, Jr., web http://linuxcommand.org/
Čtenáři ABC Linuxu, Učebnice GNU/Linuxu: Příkazová řádka
Johanka Spoustová, Pohádky z příkazové řádky
ABC Linuxu, Bash (seriál)
Machtelt Garrels, Bash guide for beginners
Mendel Cooper, Advanced Bash-scripting guide
[21] Zařízení hda reprezentuje zařízení připojené jako master na prvním IDE řadiči. Podle toho, co je k tomuto řadiči připojeno se může jednat o pevný disk nebo optickou mechaniku.