Advanced Bash History

Unix-Shells verfügen, ganz ähnlich wie Browser, über eine History genannte Aufzeichnung der zuletzt eingegebenen Befehle. Mit der Pfeiltaste nach oben können die letzten Befehle durchgescrollt werden. Die komplette Aufzeichnung lässt sich über die Eingabe von history anzeigen und listet die neuesten Befehle am Schluss der Liste auf.

History Basics

Jedem Befehl ist eine Nummer vorangestellt über die sich der jeweilige Befehl durch ein vorangestelltes ! erneut ausführen lässt. So führt etwa die Eingabe von !22 den Befehl mit der Nummer 22 erneut aus. Mit !! wird stets der letzte Befehl noch einmal ausgeführt. Diese Eingaben können auch ergänzt werden. Wurde etwa ein sudo vergessen, lässt sich das schnell mit sudo !! für den letzten Befehl ergänzen. Die history man-page listet eine Unzahl an weiteren Optionen auf, die für den effizienten Einsatz der Shell verwendet werden können. In meiner täglichen Arbeit nutze ich beispielsweise häufig den !$ Operator.

Dieser bezieht sich stets auf das letzte “Wort” eines Befehls. Hatte man etwa eine Datei per cat /etc/somefile.conf angezeigt, ist sie direkt danach per vim !$ editierbar. In der man-page finden sich, wie gesagt, noch viele weitere Möglichkeiten mit der History umzugehen. Es ist aber vor allem wichtig, dass die Shortcuts auch ihren Weg ins Muskel-Gedächtnis finden. Denn nur wenn die verschiedenen Operatoren benutzt werden können ohne groß nachzudenken machen sie auch Sinn.

Mehr History durch .bashrc

Durch Einträge in die ~/.bashrc1 kann man die Fähigkeiten der History erweitern und verbessern.

So ist es normalerweise üblich, dass die History nur nach einem sauberen exit der aktuellen Shell geschrieben wird. Stürzt die Shell ab oder hat man mehrere gleichzeitig geöffnete Fenster mit Shells2 ist die History verloren, oder kommt durcheinander oder steht nicht in allen Fenstern zur Verfügung. Diesem unhaltbaren Zustand ist glücklicherweise sehr einfach abzuhelfen. Durch das Hinzufügen von einer Zeile in der .bashrc wird die History direkt nach jedem Kommando geschrieben und steht in anderen Fenstern zur Verfügung:

PROMPT_COMMAND="history -a"

Mein absoluter Lieblingsschnipsel für die History-Erweiterung per .bashrc ist dieser:

h() { if [ -z "$1" ]; then history; else history | grep "$@"; fi; }

Hier wird eine Funktion namens h definiert. Diese führt den oben erwähnten Befehl history aus, wenn kein weiterer Parameter angegeben wird. Folgt nach dem h ein beliebiger String wird nach diesem in der Histroy gegrept. So wird etwa ein h cd alle verwendeten cd-Kommandos anzeigen.

Eine sehr praktische Sache.

Soll die Ausgabe der History ausserdem erweitert werden, so ist dieser Schnipsel zu verwenden:

export HISTTIMEFORMAT='%Y.%m.%d-%T :: ' HISTFILESIZE=50000 HISTSIZE=50000

Damit wird die Ausgabe der History um Datum und Uhrzeit der Befehle erweitert und ausserdem auf 50.000 Einträge erweitert.

Die vorgestellten Schnipsel können natürlich angepasst oder erweitert werden. Die Größe der History lässt sich auch ohne die Datumsangabe verwenden und es ist natürlich auch möglich nur das Datum oder nur die Uhrzeit zu verwenden…

Update, 09.04.2010

Ein weiterer Schnipsel aus einem Kommentar von Asmus:

bind '"\e[A"':history-search-backward 
bind '"\e[B"':history-search-forward

Hierdurch ist es möglich einen Befehl, etwa cd, zu tippen und dann mit den Pfeiltasten nur durch solche Befehle zu navigieren, die mit cd beginnen. Total super!

Ich habe hier nur die Anführungszeichen korrigiert, diese wurden in Asmus Kommentar typografisch korrekt, aber .bashrc untauglich angezeigt.

  1. Eine versteckte Datei im Homeverzeichnis, Grundlegendes zu dieser Datei hier… []
  2. Das ist hier quasi ständig der Fall… []
  • Asmus

    Also da muss ich jetzt auch erstmalig kommentieren ;-) Zusatztipps von meiner Seite sind das automatische entfernen von Duplikaten aus der History:

    export HISTCONTROL=erasedups

    und meine mittlerweile liebste Ergänzung (ich hoffe die Sonderzeichen kommen richtig an):

    bind ‘”\e[A”‘:history-search-backward bind ‘”\e[B”‘:history-search-forward

    dies führt dazu, dass mit Pfeiltaste nach oben / unten die History durchsucht und der aktuelle Befehl ergänzt wird; schreibt man cd und drückt die Pfeiltaste nach oben, erscheint dann der zuletzt genutzte Befehl der mit cd begann. Sehr praktisch wenn man sich an lange Befehlsketten nicht mehr genau erinnern kann, aber weiß “das ging mit einem scp -R los..”.

  • http://instant-thinking.de der Dennis

    Danke für die Ergänzung Asmus, ich habe deinen Code-Schnipsel als Update oben in den Post eingefügt und die Anführungszeichen korrigiert.

    Was die Duplikate angeht:

    Ich habe hier die Option HISTCONTROL=ignoredups gesetzt. Die verhindert nur direkt aufeinanderfolgende Duplikate, während erasedups überhaupt keine Duplikate zulässt.

    IMHO sind ein paar Duplikate in der History zu verschmerzen. Wenn man etwas nachvollziehen möchte, was schon einige Zeit zurück liegt, so geben einem die noch vollständig vorhandenen Befehlsketten auch etwas mehr Kontext…

  • http://knipsograf-fotografie.de Eric

    Danke für den nützlichen Beitrag.