To dopiero historia!

Historia poleceń w bashu to nieocenione narzędzie. Można go wykorzystać jeszcze lepiej dzięki kilku trikom.
historia w bashu

TL;DR

Polecenie history daje nam dostęp do  poleceń wpisanych wcześniej w konsoli. Jest kilka sposobów, by ulepszyć działanie historii – zwiększyć liczbę zapamiętanych poleceń, ułatwić wyszukanie potrzebnej sekwencji itp.

Dla każdego, kto pracuje w konsoli historia poleceń to nieocenione narzędzie. Bywa, że kopiujemy  jakiegoś „onelinera” z internetu, czasem trzeba poeksperymentować z wartością parametrów. Pamięć jest zawodna, zwłaszcza jeśli tych prób i eksperymentów było sporo. W takim przypadku możliwość prześledzenia historii poleceń jest niezwykle przydatna. Działanie historii poleceń w bashu jest regulowane różnymi zmiennymi i parametrami. Ich domyślne wartości są rozsądne, ale czasem warto jest je poprawić, żeby ten mechanizm działał jeszcze lepiej.

Pojemność historii

Polecenia nie są zapamiętywane w nieskończoność. Istnieją ograniczenia, które zapobiegają przepełnieniu pamięci albo spowolnieniu działania konsoli. Liczba pamiętanych elementów jest zapisana w dwóch zmiennych systemowych: HISTFILESIZE i HISTSIZE. Pierwsza odpowiada za wielkość pliku, w którym zapisywane są polecenia, druga ogranicza liczbę zapisów w danej sesji. Obie zmienne mają domyślną wartość 500. Jest to pozostałość z czasów, kiedy zasoby komputera były niewielkie i trzeba było je oszczędzać. Dziś, dysponując terabajtowymi dyskami i gigabajtami pamięci możemy sobie pozwolić na znaczne zwiększenie wartości tych danych. Robi się to dodając w swoim pliku .bashrc następujące linie (na końcu podam podsumowanie wszystkich danych dopisywanych do pliku konfiguracyjnego):

export HISTFILESIZE=10000
export HISTSIZE=10000

10000 poleceń to aż nadto, a nie zajmuje zasobów aż tak, żeby to było zauważalne. Jedyna niedogodność to fakt, że 10000 linii wyświetla się dość długo, zwłaszcza kiedy pracuje się na wirtualnej maszynie albo przez ssh. Na to również jest rada – podglądając listę poleceń wystarczy podać ile ostatnich linii ma zostać wyświetlonych:

history [n]

gdzie n to liczba linii (od końca) historii.

Natychmiastowy zapis

Domyślnie bash zapisuje historię poleceń na koniec sesji (po wydaniu polecenia exit). Jeśli mamy otwartych kilka konsol to taka taktyka nie zdaje egzaminu – każde okno trzyma swoją sesję, plik jest nadpisywany i nie można wykorzystać historii jednego okna w drugim. Dlatego też warto zadbać, by historia była zapisywana na bieżąco. Można to zrobić dodając w pliku konfiguracyjnym następujące dwie linie:

shopt -s histappend
PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Pierwsza linia określa, że kolejne polecenia są dopisywane do pliku, a nie nadpisują go.
Druga modyfikuje zmienną, odpowiedzialną za akcję w momencie wydania polecenia – kolejno:
history -a – dołączenie linii historii z tej sesji do pliku historii
history -c – wyczyszczenie listy historii poprzez usunięcie wszystkich wpisów
history -r – odczyt pliku historii i dołączenie zawartości do listy historii
$PROMPT_COMMAND – wykonaj polecenie.

Opis poszczególnych opcji dostępny jest po wpisaniu w konsoli history --help

Daty w historii

Czasem warto jest wiedzieć, kiedy dane polecenie zostało wykonane. Ułatwia to wyszukiwanie, może też być podstawą do jakiejś analizy swojej pracy. Ustawienie kolejnej zmiennej:

export HISTTIMEFORMAT="%d.%m.%y %H:%M:%S "

Spowoduje, że historia będzie wyświetlana z datami.

Tu uwaga: daty są rejestrowane od momentu wprowadzenia powyższego zapisu (a konkretnie od ustawienia tych zmiennych w sesji).

Wyszukiwarka

Rzecz jasna można przeszukać historię za pomocą polecenia grep:

history | grep "wyrażenie"

Jest jednak znacznie wygodniejsza metoda. Bash ma do tego specjalny skrót klawiszowy: Ctrl+r. Przyciśnięcie tej kombinacji spowoduje, że wyświetlona jest zachęta:

(reverse-i-search)`':

a konsola przechodzi w tryb przeszukiwania historii. Wpisywanie kolejnych znaków zawęża wyszukiwanie do poleceń w historii, zawierających podany ciąg. Kolejne przyciśnięcia kombinacji Ctrl+r pokazują następne wystąpienia ciągu w historii. Niezwykle wygodna metoda, zdecydowanie warta polecenia.

Bazując na tej wyszukiwarce można stworzyć w historii coś w rodzaju „zakładek”. 

Bash dysponuje komentarzem. Jeśli więc polecenie zakończymy znakiem (lub kilkoma) # oraz jakąś nazwą to wyszukanie potem takiego polecenia jest znacznie łatwiejsze – wystarczy wcisnąć kombinację Ctrl+r i wpisać “#” oraz nazwę.

Ostatnie polecenie

Historia basha daje dostęp do poleceń i pozwala na ich ponowne wykonanie poprzez wpisanie raptem kilku znaków. Przy długich poleceniach, zawierających wiele parametrów jest to duża wygoda i oszczędność czasu.

Ostatnie polecenie można powtórzyć wpisując jedynie dwa wykrzykniki (!!)

Jeśli nie chcemy powtórzyć ostatniego polecenia, a jakieś inne, możemy posłużyć się numerem, jakie wyświetla polecenie history:

!n

gdzie n to numer polecenia na liście.

Może się zdarzyć, że popełniliśmy błąd, coś poszło nie tak. Życie jest życiem i nie zawsze idzie tak, jak się spodziewamy. Niepotrzebne wpisy w historii można usunąć – żeby nie śmieciły, żeby nie zajmować pamięci itp. Najpierw należy znaleźć numer niepotrzebnego już polecenia, po prostu listując historię. Następnie wydajemy polecenie:

history -d n

gdzie n to numer kasowanego polecenia.

W ten sposób można oczyścić listę i przyspieszyć dostęp do poleceń.

Nie zapisuj spacji

Bash ma swój sposób na ominięcie zapisu jakiegoś polecenia. Może się to przydać do odśmiecenia zawartości historii, pominięcia niepotrzebnych poleceń albo… pominięcia poleceń, których nikt inny nie powinien zobaczyć. Owszem, to trochę paranoiczne, ale czy rzeczywistość wokół nas nie staje się trochę paranoiczna? Myślę, że trzeba to wziąć pod uwagę.

Zachowanie historii określa zmienna HISTCONTROL, która może zawierać następujące wartości, oddzielone dwukropkiem:

  • ignorespace Nie zapisuj poleceń, które zaczynają się od spacji
  • ignoredups Nie zapisuj polecenia jeśli jest takie samo jak poprzednie
  • ignoreboth Oba powyższe razem
  • erasedups Usuń duplikaty z całej historii

Na przykład, by mieć możliwość wymuszenia pominięcia, jednocześnie nie zaśmiecać sobie historii powtórzonymi poleceniami należy do pliku .bashrc lub .profile wpisać linię:

export HISTCONTROL=ignorespace:erasedups

Pomiń polecenia

Zazwyczaj jest kilka (lub więcej) poleceń, które nie są specjalnie interesujące z perspektywy czasu – np. ls, cd, czy samo polecenie history – ich użycie nie wnosi do naszego doświadczenia żadnej wiedzy. Na szczęście można określić zestaw poleceń, które z założenia nie będą zapisywane. Służy do tego zmienna HISTIGNORE, której zawartość jest formatowana podobnie jak HISTCONTROL – poszczególne polecenia są oddzielane dwukropkiem.

export HISTIGNORE=”ls:ps:history:cd:top:htop”

Utrwalone w konfiguracji

Wszystkie te zmiany można zapisać w pliku konfiguracyjnym i ustawić sobie sposób działania historii na stałe. Przypomnę tylko, choć pewnie wszyscy wiedzą:

  • plik ~/.profile jest odczytywany raz, przy logowaniu
  • plik ~/.bashrc jest odczytywany przy każdym otwarciu konsoli.

Globalne zmiany lepiej jest zapisywać w pliku .profile, dzięki temu plik .bashrc będzie bardziej przejrzysty – czasem trzeba tam umieścić sporo informacji.

Aby rozsądnie i wygodnie ustawić działanie historii warto w pliku konfiguracyjnym mieć następujące wpisy:

export HISTFILESIZE=10000 # rozmiar pliku z historią (w liniach)
export HISTSIZE=10000 # liczba poleceń zapamiętywanych w ramach jednej sesji
shopt -s histappend  # dopisywanie nowych poleceń, a nie nadpisywanie pliku
PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND" # natychmiastowy                       zapis polecenia
export HISTCONTROL=ignorespace:erasedups # ignoruj polecenia zaczynające się od spacji i usuń duplikaty.

Ostatnio zbyt wielu jest chętnych do zmieniania historii… Na szczęście manipulowanie historią w bashu nie ma żadnych konsekwencji – zachęcam więc do eksperymentowania, bo jest to niezwykle przydatne narzędzie.

3 komentarze
  1. Dobry, przejrzysty artykuł, można uporządkować wiedzę. Jakby jeszcze na końcu pojawiał się np. cheatsheet w pdfie do pobrania, byłaby pełnia szczęścia 🙂

  2. Możliwe, że w różnych dystrybucjach są różne ustawienia domyślnych wartości. Niemniej 1000 to niedużo i sugerowałbym tę liczbę zwiększyć.
    Plik historii nie zawiera informacji o tym, czy ktoś miał uprawnienia, czy nie. Daty będą rejestrowane tylko wtedy, gdy dodamy, wspomnianą w tekście, zmienną systemową. Historia doskonale służy wygodzie użytkowania konsoli, ale zupełnie nie nadaje się do pilnowania bezpieczeństwa….

  3. Zdaje mi się, że domyślna wartość, to 1000.
    echo $HISTSIZE – i tam pisze ile.
    A czy jest możliwość wylistowania historii poleceń, z datami i godzinami, które ktoś wykonywał bez uprawnień, bo się zalogował np. hakując kompa? Czy tylko wg opcji jw?

Komentarze są wyłączone.

Poprzedni post
Screen z Peppermint OS

Peppermint OS 11 już jest

Następny post

Bat: cat uskrzydlony

Powiązane posty