Historie
To, že si interpret příkazů uchovává jejich historii, dnes bereme jako samozřejmost. Párkrát zmáčkneme kurzor nahoru, dokud se neobjeví hledaný příkaz, upravíme, odešleme, chrochtáme blahem.
Já se však hodlám vrátit do dávnější minulosti, kdy špičkou mezi interprety byl csh. Ten už měl historii příkazů, ovšem zcela neinteraktivní. Odkazovali jste se na ni speciálními sekvencemi začínajícími vykřičníkem. Například !! znamenalo „zopakuj poslední příkaz“, !19 zopakovalo devatenáctý provedený příkaz a !-5 pátý od konce.
Proč vás obtěžuji podivnými senilními vzpomínkami? Protože některé z těchto konstrukcí jsou proklatě užitečné. Například !řetězec se vrací v historii tak dlouho, až narazí na příkaz začínající řetězcem. Ten pak provede. !gcc tedy zopakuje váš poslední překlad. Chcete-li zopakovat příkaz, který leží hlouběji v historii, je to rychlejší, než ťapat k němu kurzorem.
Čas od času se hodí i konstrukce !?řetězec?, která se vrací v historii a hledá provedený příkaz, který obsahuje zadaný řetězec. Hledá jej v celém řádku, nikoli jen na začátku.
Zmíněné odkazy na historii můžete používat jako součást řádku a doplňovat k nim další prvky. Například !gcc -O2 zopakuje poslední překlad a přidá k němu volbu „-O2“.
Moderní interprety nabízejí i interaktivní verzi prohledávání historie.
- bash
- Implicitně nemá hledání mapováno na žádnou klávesu. Doporučuji k tomuto účelu použít Ctrl-P a Ctrl-N, které kopírují funkce šipek nahoru a dolů a nebývají tudíž potřeba. Do souboru ~/.inputrc přidejte řádky:
C-p: history-search-backward C-n: history-search-forward
Změna se projeví až v nově spuštěném interpretu.
- tcsh
- Implicitně mapuje hledání v historii na klávesové sekvence Ctrl-[ p a Ctrl-[ n. Pokud byste je chtěli přemapovat na výše zmiňované Ctrl-P a Ctrl-N, použijte příkazy:
bindkey ^P history-search-backward bindkey ^N history-search-forward
Chcete-li toto chování používat stále, vložte zmíněné příkazy do souboru ~/.tcshrc (případně ~/.cshrc)
Když po provedení zmiňovaných úprav napíšete na příkazový řádek gcc a stisknete Ctrl-P, poskočí interpret v historii na nejbližší předchozí příkaz začíznající „gcc“. Klávesami Ctrl-P a Ctrl-N pak můžete poskakovat mezi jednotlivými příkazy s tímto začátkem.
Další vychytávkou staré gardy je konstrukce ^raz^dva, která vezme předchozí příkaz, vyhledá v něm první výskyt řetězce „raz“ a nahradí jej řetězcem „dva“. Takto upravený příkaz pak provede. Například když chcete provést
program soubor1.dat
program soubor2.dat
zadejte
program soubor1.dat
^1^2
Je to rychlejší než měnit jedničku na dvojku interaktivně pomocí editačních kláves.
Poslední historizující konstrukcí, o které se zmíním, je používání parametrů z historie. Nejčastější jsou odkazy na parametry předchozího příkazu:
Tabulka č. 112 !* všechny parametry !^ první parametr !$ poslední parametr
To lze využít například při opatrném mazání. Nejprve si příkazem ls nechám vypsat kandidáty ke smazání
ls *.bak *.old *.tmp
a pokud jsem se seznamem souborů spokojen, nechám totéž vymazat
rm !*
Tyto „historické“ parametry vám občas přijdou k duhu i při vytváření aliasů. Úplně stejně se totiž odkazujete v definici aliasu na parametry, které uživatel zadá při jeho použití. Zde se jedná o takzvanou budoucí historii ;-)
S odkazy na parametry lze činit řadu kouzel (včetně vytahování jejich částí, odřezávání přípon a podobně). To však při interaktivní práci upotřebíte jen vzácně. Častěji budete tyto kejkle potřebovat při vytváření skriptů, ovšem v takovém případě byste neměli být líní podívat se do manuálové stránky odpovídajícího interpretu.
Doplňování
Doplňování názvů příkazů, souborů a dalších komponent dnes bereme jako samozřejmost. Napíši prvních několik znaků, stisknu tabulátor a interpret dokončí slovo za mne.
Pokud je začátek jednoznačný. Chování při nejednoznačnosti je do značné míry ovlivnitelné. Přiznám se, že implicitní nastavení mi příliš nevyhovuje. Chtěl bych, abych při nejednoznačnosti okamžitě dostal nabídku jmen, která lze získat z daného začátku. Podívejme se, jak to zařídit.
- bash
- Do souboru ~/.inputrc přidejte řádek
set show-all-if-ambiguous on
Nyní při nejednoznačnosti místo obvyklého zatroubení dostanete nabídku dostupných jmen, což je přesně to, co člověk zpravidla potřebuje.
Seznam nabízených souborů můžete omezit pomocí proměnné prostředí FIGNORE. Obsahuje dvojtečkami oddělovaný seznam přípon, které mají být při doplňování ignorovány. Například
FIGNORE='.o:~:.bak' export FIGNORE
zajistí, že při doplňování si interpret nebude všímat souborů, jejichž jména končí „.o“, „~“ či „.bak“. Existuje i proměnná GLOBIGNORE, kde můžete zadat jména ignorovaných souborů pomocí žolíkových znaků. Ovšem v reálném životě přípony zpravidla postačí. Má-li mít nastavení trvalý účinek, musíte je provést ve startovacím souboru (~/.bash_profile, ~/.bash_login či ~/.profile).
- tcsh
- Zde je třeba nastavit proměnnou interpretu
set autolist
Lze to udělat interaktivně, pro trvalý účinek vložte uvedený příkaz do souboru ~/.tcshrc.
Také tcsh umožňuje definovat přípony, které budou při doplňování ignorovány. K tomuto účelu zde slouží proměnná interpretu fignore. Stejného účinku jako výše bychom dosáhli příkazem
set fignore = (.o \~ .bak)
Příkaz patří do souboru ~/.tcshrc.
Interprety dovedou doplňovat ledacos:
- jméno příkazu (u prvního slova na řádku)
- jméno souboru/adresáře (u dalších slov na řádku)
- jméno uživatele (začíná-li slovo znakem „~“)
- jméno proměnné (začíná-li slovo znakem „$“)
- jméno počítače (začíná-li slovo znakem „@“)
Pro kutily je k dispozici příkaz complete, pomocí kterého mohou s doplňováním vysloveně čarovat. Jeho prostřednictvím lze definovat, jak má vypadat seznam možností, z nichž se bude vybírat doplňovaný řetězec. Příkaz se sice u obou interpretů jmenuje stejně, jeho tvar se však zásadně liší.
- bash
- bash nabízí příkaz complete až v nejnovějších verzích (verze 2.04 jej zcela jistě má). Má podobu
complete konstrukce_seznamu příkaz
kde konstrukce_seznamu určuje, jak se bude vytvářet seznam kandidátů na doplnění pro daný příkaz. Významnou roli v něm zpravidla hraje -A akce, která vytvoří základní seznam. Dostupných akcí je zhruba dvacet, mezi nejběžnější patří file (seznam souborů), directory (seznam adresářů) či command (seznam příkazů).
Na vzniklý seznam lze pak nasadit filtr -X výraz, kterým omezíte sortiment možností. Výrazem je běžný žolíkový znak a filtr vyřadí všechna jména, která mu vyhoví. Pokud výraz začíná vykřičníkem, vyhovující jména jsou naopak ponechána a vyřadí se vše ostatní.
Špetka ilustračních příkladů:
complete -A directory cd
zařídí, že příkazu cd budou v prvním parametru doplňovány jen adresáře.complete -A command man
zapne doplňování jmen příkazů v parametrech příkazu man.complete -A file -X ‚!*.ps‘ ghostview
si bude při doplňování parametrů příkazu ghostview všímat jen souborů s příponou „.ps“. - tcsh
- Tento interpret nabízí complete již dost dlouho, takže je zjevné, kdo od koho opisoval ;-) Má odpudivější syntaxi, větší schopnosti a především je v manuálové stránce mnohem lépe popsán (včetně pokročilejších příkladů, které u bash zcela chybí). Základní tvar je
complete příkaz slovo/vzor/seznam/
Slovo určuje, které slovo (vůči aktuálnímu) se doplňuje. Nejběžnějšími hodnotami jsou c (aktuální), n (následující) a p (slovo na dané pozici). Vzor pak stanoví vzor či pozici, kterému musí aktuální slovo vyhovět, aby došlo k aktivaci pravidla. Můžete tedy vytvořit několik pravidel pro tentýž příkaz.
Seznam definuje seznam hodnot, které budou brány v úvahu při doplňování. Nejčastěji používané hodnoty: f (jména souborů), d (adresáře), c (příkazy). Můžete sem také zapsat příkaz uzavřený do obrácených apostrofů a jeho výstup pak bude interpretován jako seznam možností. Za seznam můžete ještě připojit dvojtečku a žolíkový výraz. Ten pak ponechá v seznamu jen jména, která mu vyhovují.
Příklady:
complete cd ‚p/1/d/‘
zajistí, že příkazu cd budou doplňovány jen adresáře.complete man ‚p/*/c/‘
doplňuje příkazu man názvy příkazů.complete ghostview ‚p/*/f:*.ps/‘
doplňuje v parametrech ghostview jen soubory s příponou „.ps“.complete kill ‚p/*/
ps | awk \{print\ \$1\}
/‘
doplňuje příkazu kill čísla aktivních procesů.complete find ‚n/-user/u/‘
doplňuje příkazu find v parametru následujícím za „-user“ jen jména uživatelů.
A to je pro dnešek vše. Příště se podíváme na opravování překlepů, ukážeme si několik triků pro práci s adresáři a také si povíme něco málo o nastavování promptu.