Shell Linuxu ukládá historii příkazů, které spouštíte, a můžete v něm prohledávat a opakovat příkazy, které jste spustili v minulosti. Jakmile pochopíte příkaz historie Linuxu a jak jej používat, může výrazně zvýšit vaši produktivitu.
Table of Contents
Manipulace s historií
Tak jako George Santayana slavně řekl„Ti, kteří si nepamatují minulost, jsou odsouzeni ji opakovat.“ Bohužel na Linuxu, pokud si nepamatujete minulost, nemůžete ji opakovat, i když byste chtěli.
Tehdy se hodí příkaz historie Linuxu. Umožňuje vám zkontrolovat a zopakovat vaše předchozí příkazy. Cílem není jen podpořit lenost nebo ušetřit čas – ve hře je také faktor efektivity (a přesnosti). Čím je příkaz zdlouhavější a složitější, tím je těžší si jej zapamatovat a napsat, aniž by došlo k chybě. Existují dva typy chyb: jedna, která příkazu brání v práci, a druhá, která příkazu umožní pracovat, ale způsobí, že provede něco neočekávaného.
Příkaz historie tyto problémy odstraňuje. Stejně jako většina příkazů Linuxu je v tom víc, než si myslíte. Pokud se však naučíte používat příkaz historie, může to zlepšit vaše používání příkazového řádku Linuxu každý den. Je to dobrá investice vašeho času. Existují mnohem lepší způsoby, jak použít příkaz historie, než jen opakované stisknutí šipky nahoru.
Příkaz historie
Ve své nejjednodušší podobě můžete použít příkaz historie pouhým zadáním jeho názvu:
history
Seznam dříve použitých příkazů je pak zapsán do okna terminálu.
Příkazy jsou očíslovány, přičemž poslední použité příkazy (ty s nejvyššími čísly) jsou na konci seznamu.
Chcete-li zobrazit určitý počet příkazů, můžete zadat číslo do historie na příkazovém řádku. Chcete-li například zobrazit posledních 10 příkazů, které jste použili, zadejte následující:
history 10
Stejného výsledku můžete dosáhnout, pokud propojíte historii potrubím ocasní příkaz. Chcete-li tak učinit, zadejte následující:
history | tail -n 10
Opakování příkazů
Pokud chcete znovu použít příkaz ze seznamu historie, zadejte vykřičník (!) a číslo příkazu bez mezer mezi nimi.
Chcete-li například zopakovat příkaz číslo 37, zadejte tento příkaz:
!37
Chcete-li zopakovat poslední příkaz, zadejte znovu dva vykřičníky bez mezer:
!!
To může být užitečné, když zadáte příkaz a zapomenete použít sudo. Zadejte sudo, jedna mezera, dvojité vykřičníky a stiskněte Enter.
Pro následující příklad jsme zadali příkaz, který vyžaduje sudo. Místo přepisování celého řádku si můžeme uložit spoustu úhozů a jednoduše napsat sudo !!, jak je ukázáno níže:
mv ./my_script.sh /usr/local/bin/
sudo !!
Můžete tedy zadat odpovídající číslo ze seznamu pro opakování příkazu nebo použít dvojité vykřičníky pro opakování posledního příkazu, který jste použili. Co když však chcete zopakovat pátý nebo osmý příkaz?
K opakování můžete použít jeden vykřičník, pomlčku (-) a číslo libovolného předchozího příkazu (opět bez mezer).
Chcete-li zopakovat 13. předchozí příkaz, zadejte následující:
!-13
Hledání příkazů podle řetězce
Chcete-li zopakovat poslední příkaz, který začíná konkrétním řetězcem, můžete zadat vykřičník a poté řetězec bez mezer a stisknout Enter.
Chcete-li například zopakovat poslední příkaz, který začínal sudo, zadejte tento příkaz:
!sudo
Je v tom však prvek nebezpečí. Pokud poslední příkaz, který začal sudo, není ten, o kterém si myslíte, že je, spustíte špatný příkaz.
Chcete-li však poskytnout záchrannou síť, můžete použít modifikátor :p (tisk), jak je znázorněno níže:
!sudo:p
To dává historii pokyn k vytištění příkazu do okna terminálu, nikoli k jeho provedení. To vám umožní vidět příkaz předtím, než jej použijete. Pokud je to požadovaný příkaz, stiskněte šipku nahoru a poté jej použijte klávesou Enter.
Pokud chcete najít příkaz, který obsahuje konkrétní řetězec, můžete použít vykřičník a otazník.
Chcete-li například najít a provést první odpovídající příkaz, který obsahuje slovo „aliasy“, zadejte tento příkaz:
!?aliases
To najde jakýkoli příkaz, který obsahuje řetězec „aliasy“, bez ohledu na to, kde se v řetězci vyskytuje.
Interaktivní vyhledávání
Interaktivní vyhledávání vám umožňuje procházet seznamem odpovídajících příkazů a opakovat ten, který chcete.
Pro zahájení vyhledávání stačí stisknout Ctrl+r.
Při psaní vyhledávacího klíče se objeví první odpovídající příkaz. Písmena, která napíšete, se objeví mezi zadním zaškrtnutím (`) a apostrofem (‚). Odpovídající příkazy se aktualizují při psaní každého písmene.
Pokaždé, když stisknete Ctrl+r, hledáte zpětně další odpovídající příkaz, který se objeví v okně terminálu.
Když stisknete Enter, zobrazený příkaz se provede.
Chcete-li upravit příkaz před jeho provedením, stiskněte šipku vlevo nebo vpravo.
Příkaz se objeví na příkazovém řádku a můžete jej upravit.
K prohledávání seznamu historie můžete použít další nástroje Linuxu. Například k přenosu výstupu z historie do grep a hledat příkazy, které obsahují řetězec „aliasy“ můžete použít tento příkaz:
history | grep aliases
Úprava posledního příkazu
Pokud potřebujete opravit překlep a poté příkaz zopakovat, můžete jej upravit pomocí stříšky (^). Je to skvělý trik, který můžete mít v rukávu, kdykoli překlepnete příkaz nebo chcete příkaz znovu spustit s jinou možností nebo parametrem příkazového řádku.
Chcete-li jej použít, zadejte (bez mezer) stříšku, text, který chcete nahradit, další stříšku, text, kterým jej chcete nahradit, další stříšku a stiskněte Enter.
Předpokládejme například, že zadáte následující příkaz a omylem zadáte „shhd“ místo „sshd“:
sudo systemctl start shhd
Můžete to snadno opravit zadáním následujícího:
^shhd^sshd^
Příkaz se provede s „shhd“ opraveným na „sshd“.
Odstranění příkazů ze seznamu historie
Příkazy můžete také odstranit ze seznamu historie pomocí volby -d (smazat). Není důvod uchovávat váš chybně napsaný příkaz v seznamu historie.
K jeho nalezení můžete použít grep, předat jeho číslo do historie pomocí volby -d, abyste jej smazali, a poté znovu hledat, abyste se ujistili, že je pryč:
history | grep shhd
history -d 83
history | grep shhd
Volbě -d můžete také předat řadu příkazů. Chcete-li odstranit všechny položky seznamu od 22 do 32 (včetně), zadejte tento příkaz:
history -d 22 32
Chcete-li odstranit pouze posledních pět příkazů, můžete zadat záporné číslo, například:
history -d -5
Ruční aktualizace souboru historie
Když se přihlásíte nebo otevřete terminálovou relaci, seznam historie se načte ze souboru historie. V Bash je výchozí soubor historie .bash_history.
Jakékoli změny, které provedete v aktuální relaci okna terminálu, se zapíší do souboru historie pouze při zavření okna terminálu nebo odhlášení.
Předpokládejme, že chcete otevřít další okno terminálu pro přístup k úplnému seznamu historie, včetně příkazů, které jste zadali v prvním okně terminálu. Volba -a (all) vám to umožňuje provést v prvním okně terminálu před otevřením druhého.
Chcete-li jej použít, zadejte následující:
history -a
Příkazy se tiše zapisují do souboru historie.
Pokud chcete zapsat všechny změny do seznamu historie do souboru historie (pokud jste například smazali některé staré příkazy), můžete použít volbu -w (zápis), takto:
history -w
Vymazání seznamu historie
Chcete-li vymazat všechny příkazy ze seznamu historie, můžete použít volbu -c (vymazat), a to následovně:
history -c
Pokud chcete navíc vynutit tyto změny v souboru historie, použijte volbu -w, například:
history -w
Zabezpečení a soubor historie
Pokud používáte aplikace, které vyžadují zadání citlivých informací (jako jsou hesla) do příkazového řádku, nezapomeňte, že se také uloží do souboru historie. Pokud nechcete, aby se určité informace ukládaly, můžete je pomocí následující struktury příkazů okamžitě odstranit ze seznamu historie:
special-app my-secret-password;history -d $(history 1)
history 5
Tato struktura obsahuje dva příkazy oddělené středníkem (;). Pojďme si to rozebrat:
special-app: Název programu, který používáme.
my-secret-password: Tajné heslo, které musíme zadat pro aplikaci na příkazovém řádku. Toto je konec prvního příkazu.
historie -d: V příkazu dva vyvoláme volbu -d (smazat) historie. To, co se chystáme odstranit, je v další části příkazu.
$(history 1): Toto používá substituci příkazů. Část příkazu obsažená v $() se provádí v podskořápce. Výsledek tohoto provedení se zveřejní jako text v původním příkazu. Příkaz historie 1 vrátí předchozí příkaz. Takže si můžete představit druhý příkaz jako history -d „poslední příkaz zde“.
Pomocí příkazu history 5 se můžete ujistit, že příkaz obsahující heslo byl odstraněn ze seznamu historie.
Existuje však ještě jednodušší způsob, jak to udělat. Protože Bash ve výchozím nastavení ignoruje řádky začínající mezerou, vložte mezeru na začátek řádku následovně:
special-app another-password
history 5
Příkaz s heslem není přidán do seznamu historie. Důvod, proč tento trik funguje, je obsažen v souboru .bashrc.
Soubor .bashrc
Soubor .bashrc se spustí pokaždé, když se přihlásíte nebo otevřete okno terminálu. Obsahuje také některé hodnoty, které řídí chování příkazu historie. Pojďme tento soubor upravit pomocí gedit.
Zadejte následující:
gedit .bashrc
V horní části souboru vidíte dvě položky:
HISTSIZE: Maximální počet položek, které může seznam historie obsahovat.
HISTFILESIZE: Limit počtu řádků, které může soubor historie obsahovat.
Tyto dvě hodnoty se vzájemně ovlivňují následujícími způsoby:
Když se přihlásíte nebo spustíte relaci okna terminálu, seznam historie se naplní ze souboru .bash_history.
Když zavřete okno terminálu, maximální počet příkazů nastavený v HISTSIZE se uloží do souboru .bash_history.
Pokud je povolena volba prostředí histappend, příkazy se připojí k .bash_history. Pokud histappend není nastaven, .bash_history se přepíše.
Po uložení příkazů ze seznamu historie do .bash_history je soubor historie zkrácen tak, aby neobsahoval více než HISTFILESIZE řádků.
V horní části souboru také uvidíte položku pro hodnotu HISTCONTROL.
Tuto hodnotu můžete nastavit, abyste mohli provést některou z následujících akcí:
ignorespaces: Řádky začínající mezerou nejsou přidány do seznamu historie.
ignoredups: Do souboru historie se nepřidávají duplicitní příkazy.
ignoreboth: Povolí obě výše uvedené.
Můžete také uvést konkrétní příkazy, které nechcete přidat do seznamu historie. Oddělte je dvojtečkou (:) a vložte je do uvozovek (“…”).
Chcete-li do souboru .bashrc přidat řádek a nahradit příkazy, které chcete ignorovat, postupujte podle této struktury:
export HISTIGNORE="ls:history"
Použití časových razítek
Pokud chcete do seznamu historie přidat časová razítka, můžete použít nastavení HISTIMEFORMAT. Chcete-li to provést, stačí do souboru .bashrc přidat řádek jako je následující:
export HISTTIMEFORMAT="%c "
Všimněte si, že před uvozovkami je mezera. Tím se zabrání tomu, aby se časové razítko spojilo s příkazy v seznamu příkazů.
Nyní, když spustíte příkaz historie, uvidíte datum a čas. Všimněte si, že všechny příkazy, které byly v seznamu historie před přidáním časových razítek, budou opatřeny časovým razítkem s datem a časem prvního příkazu, který obdrží časové razítko. V tomto příkladu uvedeném níže to byl příkaz 118.
To je velmi rozvláčné časové razítko. K upřesnění však můžete použít jiné tokeny než %c. Další tokeny, které můžete použít, jsou:
%d: Den
%m: Měsíc
%y: Rok
%H: Hodina
%M: Minuty
%S: Sekundy
%F: Celé datum (formát rok-měsíc-datum)
%T: Čas (formát hodina:minuty:sekundy)
%c: Kompletní datum a čas (formát den-datum-měsíc-rok a hodina:minuty:sekundy)
Pojďme experimentovat a použít několik různých tokenů:
export HISTTIMEFORMAT="%d n%m %T "
Výstup používá den, měsíc a čas.
Pokud však odstraníme den a měsíc, zobrazí se pouze čas.
Jakékoli změny provedené v HISTIMEFORMAT se použijí na celý seznam historie. To je možné, protože čas pro každý příkaz je uložen jako počet sekund od epochy Unixu. Direktiva HISTTIMEFORMAT jednoduše určuje formát použitý k vykreslení tohoto počtu sekund do stylu čitelného pro člověka, jako například:
export HISTTIMEFORMAT="%T "
Náš výstup je nyní lépe ovladatelný.
K auditu můžete také použít příkaz historie. Někdy vám kontrola příkazů, které jste použili v minulosti, může pomoci zjistit, co mohlo způsobit problém.
Stejně jako v životě můžete i na Linuxu použít příkaz history, abyste znovu prožili dobré časy a poučili se ze špatných.