Linux / Befehl history: Shell-Befehlsverlauf überprüfen und wiederverwenden

Der Befehl history in Bash zeigt vorherige Befehle an, die von der aktuellen Shell gespeichert wurden, zusammen mit ihren Nummern, und wird verwendet, um Elemente zu suchen, erneut auszuführen, zu löschen oder mit der History-Datei zu synchronisieren. Um nur die neuesten wenigen Befehle anzuzeigen, verwenden Sie history 20; um nach einem bestimmten String zu suchen, verwenden Sie history | grep 'search term'; und um Befehle beim Tippen schnell zu finden, verwenden Sie Ctrl+r.

history ist ein eingebauter Befehl in Bash. Die Erklärung in diesem Artikel basiert auf Bash, und andere Shells wie Zsh oder Fish können unterschiedliche History-Dateien und Einstellungen haben.

Was ist der history-Befehl?

Bash speichert von Benutzern in einer interaktiven Shell eingegebene Befehle in einer Speicherhistorienliste. history ist ein Befehl, der es Ihnen ermöglicht, diese Liste anzuzeigen und zu bearbeiten sowie die durch HISTFILE angegebene Historiendatei zu lesen oder zu schreiben.

Die Standarddatei history ist normalerweise ~/.bash_history. Wenn Bash startet, liest es diese Datei, um die Speicher-history-Liste zu erstellen, und beim normalen Beenden der Shell speichert es die aktuelle history in die Datei. Detailliertes Verhalten ist in der GNU Bash History Facilities Dokumentation zu finden.

Die Befehlshistorie ist eine Komfortfunktion, kein Sicherheitsprotokoll. Benutzer können Einträge löschen, und wenn die Shell abnormal beendet wird oder die Historienaufzeichnung deaktiviert ist, wird sie möglicherweise nicht gespeichert.

Grundlegende Verwendung

Wenn sie ohne Optionen ausgeführt wird, wird die Historie der aktuellen Bash-Sitzung mit Nummern angezeigt.

history

Ein Beispiel für die Ausgabe ist wie folgt.

  241  apt update
  242  systemctl status ssh
  243  journalctl -u ssh
  244  history

Um nur einen kürzlichen Teil der Historie anzuzeigen, z. B. die letzten 20 Einträge, geben Sie eine Zahl an.

history 20
Format Funktion Zu beachtende Punkte
history n Die letzten n Einträge anzeigen Sie basiert auf der Speicherliste der aktuellen Shell.
history -c Die gesamte aktuelle Aufzeichnungsliste löschen Der Zustand anderer Shell-Sitzungen und Dateien sollte separat betrachtet werden.
history -d number Löschen Sie das angegebene Element Überprüfen Sie zuerst, ob die zu löschende Nummer korrekt ist.
history -a Fügen Sie neue Elemente aus dieser Sitzung am Ende der Datei hinzu HISTFILE muss gesetzt werden.
history -n Fügen Sie neue Einträge aus der Datei in die aktuelle Liste ein Nützlich beim Importieren von Datensätzen, die in einer anderen Sitzung hinzugefügt wurden.
history -r Fügen Sie die gesamte Verlaufdatei in die aktuelle Liste ein Darf doppelte Einträge, die bereits existieren, erzeugen.
history -w Überschreiben Sie die Verlaufdatei mit der aktuellen Liste Wenn mehrere Terminals geöffnet sind, kann dies den Verlauf anderer Sitzungen beeinflussen.
history -p expression Nur die Ergebnisse der Verlaufserweiterung ausgeben Es ist nützlich, um das erweiterte Ergebnis von ! vor der Ausführung zu überprüfen.
history -s command Zum Verlauf hinzufügen, ohne den Befehl auszuführen Es wird als letzter Eintrag der aktuellen Verlaufsliste hinzugefügt.

Für die genauen Definitionen und Rückgabestatus jeder Option, siehe die GNU Bash History Builtins-Dokumentation.

Durchsuchen vorheriger Befehle

Filtern der Liste mit grep

Wenn Sie nur die Zeilen im Verlauf sehen möchten, die eine bestimmte Zeichenfolge enthalten, verwenden Sie grep zusammen mit einer Pipe.

history | grep 'systemctl'

Um die Groß- und Kleinschreibung zu ignorieren, verwenden Sie grep -i.

history | grep -i 'nginx'

Diese Methode ist praktisch, um Ergebnisse zu überprüfen, aber der aktuelle Suchbefehl, der in der Ausgabe enthalten ist, kann auch in den Ergebnissen erscheinen.

Suche während des Tippens mit Strg+r

Wenn Bash den grundlegenden Emacs-Bearbeitungsmodus verwendet, können Sie eine rückwärts inkrementelle Suche nach vorherigen Befehlen mit Ctrl+r durchführen. Jedes Mal, wenn Sie ein Zeichen zum Suchen eingeben, wird der zuletzt passende Eintrag angezeigt, und durch erneutes Drücken von Ctrl+r wechseln Sie zum nächstälteren Ergebnis.

  • Enter: Führt den angezeigten Befehl aus.
  • Pfeiltasten nach links/rechts: Beendet die Suche und bearbeitet den Befehl.
  • Ctrl+g: Bricht die Suche ab und kehrt zur ursprünglichen Eingabe zurück.

Es ist eine sichere Vorgehensweise, die Suche kurz vor der Ausführung mit den Pfeiltasten zu beenden, um den Befehl und seine Argumente zu überprüfen. Die Suchmethode wird in der GNU Readline-Dokumentation zur Befehlsuche history erklärt.

Vorherigen Befehl erneut ausführen

Historienerweiterung mit Ausrufezeichen

In interaktivem Bash können Sie die Verlaufserweiterung beginnend mit ! verwenden, um vorherige Befehle abzurufen.

Ausdruck Bedeutung Beispiel
!! Vorheriger Befehl sudo !! fügt sudo vor den vorherigen Befehl ein.
!125 Befehl mit Verlaufsnummer 125 Sie können die Nummer aus der history-Ausgabe überprüfen.
!-3 Der dritte vorherige Befehl von der aktuellen Position Wählen Sie kürzlich verwendete Befehle nach relativer Position aus.
!ssh Der zuletzt ausgeführte Befehl, der mit ssh beginnt Wenn es viele Befehle mit demselben Präfix gibt, kann ein unerwartetes Element ausgewählt werden.
!?nginx? Der zuletzt ausgeführte Befehl, der nginx enthält Suche nach einem String in der Mitte des Befehls.
^old^new^ Ersetze den ersten übereinstimmenden String des vorherigen Befehls und führe ihn aus Es wird verwendet, um kurze Tippfehler zu korrigieren und erneut auszuführen.

Die Verlaufserweiterung ist standardmäßig in interaktivem Bash aktiviert, wird jedoch standardmäßig in nicht-interaktiven Shell-Skripten nicht durchgeführt. Für die detaillierte Syntax siehe die GNU Bash History Expansion Dokumentation.

Überprüfen Sie das Erweiterungsergebnis, bevor Sie ausführen

!number und !string können den gefundenen Befehl sofort ausführen, seien Sie also besonders vorsichtig, wenn Befehle zum Löschen, Ändern von Berechtigungen oder Herunterfahren des Systems im Verlauf enthalten sind. Wenn Sie den Ausdruck in Anführungszeichen an history -p übergeben, können Sie das Erweiterungsergebnis überprüfen, ohne es auszuführen.

history -p '!!'
history -p '!ssh'

In Bash mit Readline ermöglicht das Setzen der folgenden Option, dass das Ergebnis der Verlaufserweiterung zuerst im Bearbeitungspuffer angezeigt wird, ohne sofort ausgeführt zu werden.

shopt -s histverify

In mehreren Terminalumgebungen, in denen sich Zahlen leicht ändern können, ist es oft sicherer, zuerst mit Ctrl+r zu suchen, den Inhalt zu überprüfen und dann auszuführen.

Befehlsverlauf löschen

Ein bestimmtes Element löschen

Überprüfen Sie zuerst die Nummer mit history und löschen Sie dann den entsprechenden Eintrag aus der Verlaufsliste des Speichers mit der Option -d.

history -d 125

Wenn das aktuelle Bash die Bereichslöschung unterstützt, können Sie auch eine Start- und Endnummer angeben.

history -d 120-125

Um die Löschungen in der aktuellen Verlaufsdatei widerzuspiegeln, können Sie die Liste überprüfen und dann history -w ausführen. Seien Sie jedoch darauf vorbereitet, dass andere Terminalsitzungen beim Beenden möglicherweise den vorherigen Verlauf wieder in die Datei schreiben. Stellen Sie also sicher, dass keine mehreren Sitzungen geöffnet sind.

Löschen Sie die gesamte aktuelle Liste

Die Option -c löscht alle Einträge in der Verlaufsliste im Speicher der aktuellen Shell.

history -c

Um die Historien-Datei zu aktualisieren, damit sie mit der aktuellen Liste übereinstimmt, sollten Sie verstehen, wie history -w funktioniert, bevor Sie sie verwenden. Das Löschen der Historie richtet sich nur auf die Shell-Historie und entfernt keine Systemprotokolle, Prüfprotokolle, Backups oder die Historie von anderen Terminals.

Historien-Datei und mehrere Terminal-Sitzungen

Bash hat für jede laufende Shell eine separate Speicherhistorienliste. Standardmäßig erscheinen Befehle, die gerade in einem anderen Terminal ausgeführt wurden, möglicherweise nicht sofort in der history des aktuellen Terminals.

Befehl Verhalten zwischen Historien-Datei und aktueller Sitzung
history -a Fügt neue Einträge aus der aktuellen Sitzung, die noch nicht in der Datei gespeichert wurden, an das Ende der Datei an.
history -n Fügt neue Zeilen aus der Verlauf-Datei, die die aktuelle Sitzung noch nicht gelesen hat, zur Speicherliste hinzu.
history -r Hängt den gesamten Inhalt der Verlauf-Datei an das Ende der aktuellen Speicherliste an.
history -w Überschreibt die Verlauf-Datei mit der gesamten aktuellen Speicherliste.

Um neue Einträge aus einem anderen Terminal zu übernehmen, fügen Sie diese zuerst in die Datei in diesem Terminal mit history -a ein und lesen Sie sie dann im aktuellen Terminal mit history -n ein.

history -a
history -n

Sie können die Option histappend verwenden, um neue Einträge hinzuzufügen, anstatt die Verlauf-Datei beim Beenden der Shell zu überschreiben.

shopt -s histappend

Um diese Einstellung weiterhin zu verwenden, fügen Sie sie zum ~/.bashrc des Benutzers hinzu. Es gibt auch eine Möglichkeit, PROMPT_COMMAND so einzustellen, dass es bei jeder Eingabeaufforderung von mehreren Terminals automatisch synchronisiert wird, aber Sie sollten es nicht überschreiben, ohne den aktuellen Wert zu überprüfen, da bestehende Einstellungen oder Programme diese Variable verwenden könnten.

Historienbezogene Umgebungsvariableneinstellungen

Variable Rolle
HISTFILE Der Pfad zu der Datei, in der die Historie gespeichert wird. Der übliche Standardwert ist ~/.bash_history.
HISTSIZE Die maximale Anzahl von Befehlen, die in der aktuellen Shell-Historienliste gespeichert werden.
HISTFILESIZE Begrenzt die maximale Größe der Historiendatei in Bezug auf Zeilen.
HISTCONTROL Legt Speicherregeln fest, wie zum Beispiel Befehle, die mit einem Leerzeichen beginnen, oder aufeinanderfolgende doppelte Befehle nicht aufzuzeichnen.
HISTIGNORE Geben Sie Befehlsmuster an, die vom Aufzeichnen ausgeschlossen werden sollen, getrennt durch Doppelpunkte.
HISTTIMEFORMAT Geben Sie das Datums- und Zeitformat an, das in der Ausgabe von history angezeigt werden soll.

Zum Beispiel halten die folgenden Einstellungen 5.000 Einträge im Speicher und 10.000 Einträge in der Verlaufdatei, reduzieren Befehle, die mit einem Leerzeichen beginnen, sowie doppelte Befehle und zeigen Datum und Uhrzeit an.

HISTSIZE=5000
HISTFILESIZE=10000
HISTCONTROL=ignoreboth:erasedups
HISTTIMEFORMAT='%F %T '
shopt -s histappend

Um dies fortlaufend anzuwenden, fügen Sie die obigen Einstellungen zu ~/.bashrc hinzu, starten Sie dann eine neue Bash-Sitzung oder laden Sie die Konfigurationsdatei neu.

source ~/.bashrc

HISTCONTROL=ignoreboth wendet sowohl ignorespace als auch ignoredups an. erasedups entfernt vorherige Einträge, die mit neuen Befehlen in der history-Liste identisch sind. Detaillierte Regeln für jede Variable finden Sie in der GNU Bash Variablen-Dokumentation.

Befehlsverlauf und Sicherheit

Wenn Sie Passwörter, API-Schlüssel, Tokens oder Inhalte privater Schlüssel als Kommandozeilenargumente eingeben, können diese nicht nur in der Shell-Historie, sondern auch in Informationen über laufende Prozesse oder anderen Logs offengelegt werden. Für sensible Informationen wird empfohlen, diese nicht direkt in der Kommandozeile einzugeben, sondern die vom Programm bereitgestellte Standardeingabe, einen sicheren Anmeldeinformationsspeicher oder eine Konfigurationsdatei mit eingeschränktem Zugriff zu verwenden.

Wenn ignorespace in HISTCONTROL gesetzt ist, können Kommandos, die mit einem Leerzeichen beginnen, von der Historie ausgeschlossen werden. Sie müssen jedoch darauf achten, ob diese Einstellung tatsächlich aktiv ist, und sie verhindert andere Logs nicht, daher sollte sie nicht ausschließlich als Methode zum Schutz sensibler Informationen verwendet werden.

printf '%s\n' "$HISTCONTROL"
printf '%s\n' "$HISTFILE"

Selbst wenn Sie Einträge mit history -d oder history -c löschen, können dieselben Informationen in anderen Shell-Sitzungen, Backups, Prüfprotokollen und Anwendungsprotokollen verbleiben. Wenn Zugangsdaten offengelegt werden, löschen Sie nicht nur die Historie; Sie sollten das betroffene Passwort oder Token ungültig machen und ein neues ausstellen.

Häufige Probleme

Die neuesten Befehle aus einem anderen Terminal sind nicht sichtbar

Jede Bash-Sitzung verwendet eine unabhängige Speicherliste. Nachdem Sie history -a in dem Terminal ausgeführt haben, in dem die Befehle ausgeführt wurden, versuchen Sie, history -n in dem Terminal auszuführen, das Sie überprüfen möchten. Langfristig können Sie histappend und Shell-Initialisierungseinstellungen überprüfen.

Die Historie verschwand nach dem Schließen des Terminals

HISTFILE kann leer sein, die Schreibberechtigung für die Verlaufsdatei kann fehlen oder HISTSIZE beziehungsweise HISTFILESIZE ist auf 0 gesetzt. Wird die Shell gewaltsam beendet, kann auch das Speichern beim regulären Beenden ausbleiben. Prüfen Sie diese Bedingungen getrennt.

Die Verlaufnummern haben sich im Vergleich zu vorher geändert.

Verlaufnummern sind keine festen Kennungen, sondern die Stellung in der aktuellen Speicherliste. Wenn Sie Einträge löschen oder die Datei neu laden, um die Historie aus einer anderen Sitzung zusammenzuführen, können sich die Nummern ändern. Es ist sicherer, den Befehlinhalt zu suchen und zu überprüfen, als sich alte Nummern zu merken und auszuführen.

Können dieselben Einstellungen in Zsh oder Fish verwendet werden?

Sie können nicht unverändert angewendet werden. Selbst wenn es ein Feature namens history gibt, unterscheiden sich die Datei history und die Art und Weise, wie sie mit Umgebungsvariablen synchronisiert wird, je nach Shell. Prüfen Sie zunächst printf '%s\n' "$SHELL" und die offizielle Dokumentation Ihrer aktuellen Shell.

Zusammenfassung

history in Bash kann nicht nur verwendet werden, um vorherige Befehle anzusehen, sondern auch um bestimmte Einträge zu löschen, die History-Datei zu lesen/schreiben und zwischen Sitzungen zu synchronisieren. Für die tägliche Suche sind history | grep und Ctrl+r praktisch, und beim erneuten Ausführen unter Verwendung der History-Erweiterung ist es notwendig, zuerst den Befehlsinhalt zu überprüfen.

Um die Menge und die Speicherart von Datensätzen zu ändern, überprüfen Sie zusammen HISTSIZE, HISTFILESIZE, HISTCONTROL, HISTTIMEFORMAT und histappend. Die Zwecke anderer Befehle können nach Aufgabe in der Liste der Linux-Befehle gefunden werden.