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.




