BASH: historie příkazů a citlivé údaje
Při práci na příkazové řádce v BASHi se nám ukládá historie zadaných příkazů. To je velmi užitečné – k dříve napsaným příkazům se můžeme vrátit (šipky nahoru/dolů) nebo v nich hledat (Ctrl+R) a historie se uchovává i po odhlášení (v souboru ~/.bash_history
). Někdy nám to ale může vadit – proto si teď ukážeme malý trik, jak některé příkazy do historie nezahrnout.
Dejme tomu, že třeba kopírujeme nějaký soubor a nechceme, aby jeho jméno figurovalo v historii příkazů. V takové situaci stačí před příkaz přidat jednu mezeru. Jednoduše místo "cp něco.txt někam.txt
" napíšeme " cp něco.txt někam.txt
" – příkaz se sice provede, ale neuloží se do souboru s historií a ani se k němu nepůjde vrátit pomocí šipek nebo Ctrl+R.
Pokud by vám to náhodou nefungovalo, zkontrolujte si nastavení následující proměnné:
$ echo $HISTCONTROL ignoredups:ignorespace
Více viz man bash
.
Trochu drastičtějším řešením je promazání celé historie, která ještě nebyla uložena na disk: history -c
.
Práce ve více oknech (terminálech)
Pokud pracujeme ve více terminálech současně, historie příkazů se nesdílí. To většinou nevadí a stačí, když se historie uloží do .bash_history
při zavření terminálu. Ale někdy chceme provést příkaz zadaný do jednoho okna v jiném – pak se nám budou hodit následující příkazy:
history -a # uložit aktuální historii history -n # načíst historii
Také si můžeme udělat alias, který provede oboje:
echo "alias hh='history -a; history -n'" >> .bash_aliases
Pozor na hesla
Výše jsme si uvedli, jak zabránit zařazení některých příkazů do historie (přidat mezeru). Kromě toho, že si někdo přečte soubor s historií, je tu ale další možnost vyzrazení citlivých informací: běžící procesy a jejich parametry jsou vidět ve výpisu procesů (ps aux
případně rovnou číst /proc
). Což je problém, pokud by jako parametr příkazu bylo třeba heslo – jiný uživatel, který je zrovna přihlášen na stejném počítači by ho mohl vidět.
Někoho možná napadne, že by pomohlo uložit heslo do souboru a pak ho předat příkazu takto:
nějaký-příkaz --heslo `cat heslo.txt`
Jenže to samozřejmě nefunguje resp. je to úplně na nic. Výraz uvedený v `…`
případně v $(…)
je interpretován BASHem (jinak to ani není možné – příkaz nějaký-příkaz
těmto výrazům nemůže rozumět). Takže se nejdříve vyhodnotí cat heslo.txt
a až jeho výstup se předá jako parametr prvního příkazu – tudíž se heslo objeví ve výpisu procesů.
Kdyby tomu náhodou někdo nevěřil, může si sám vyzkoušet:
$ echo 10 > heslo.txt $ sleep `cat heslo.txt` & [1] 15914 $ ps aux | grep sleep franta 15914 0.0 0.0 6948 584 pts/4 S 22:23 0:00 sleep 10
Místo „10“ si představte nějaké tajné heslo, které by bylo takto vyzrazeno.
Hesla prostě mezi parametry příkazů nepatří. A žádný rozumný program vás nebude nutit takto hesla zadávat a dost možná nebude ani tuto možnost nabízet. Hesla bývají uložená v souboru (např. .pgpass
pro PostgreSQL, .my.cnf
pro MySQL) nebo se používá asymetrická kryptografie (např. SSH, OpenSSL, GPG) nebo se heslo zadává interaktivně. Každopádně není důvod je vystavovat ve výpisu procesů.