Die Linux-Shell protokolliert eine Historie der ausgeführten Befehle. Diese Chronik erlaubt es Ihnen, frühere Befehle aufzurufen und wiederzuverwenden. Wenn Sie mit dem Linux-Befehl `history` und seiner Anwendung vertraut sind, können Sie Ihre Produktivität erheblich steigern.
Umgang mit der Befehlshistorie
Wie der bekannte George Santayana sagte: „Wer sich nicht an die Vergangenheit erinnern kann, ist verdammt, sie zu wiederholen.“ In Linux kann man die Vergangenheit jedoch durchaus wiederholen, solange man sich daran erinnern kann.
Hier kommt der Linux-Befehl `history` ins Spiel. Er ermöglicht es Ihnen, Ihre vorherigen Eingaben zu prüfen und zu reproduzieren. Dies dient nicht nur der Bequemlichkeit oder Zeitersparnis, sondern auch der Effizienz und Genauigkeit. Je komplexer ein Befehl ist, desto schwieriger ist es, ihn fehlerfrei im Gedächtnis zu behalten und einzugeben. Dabei gibt es zwei Arten von Fehlern: Solche, die die Ausführung verhindern und solche, die unerwartete Konsequenzen haben.
Der Befehl `history` minimiert diese Probleme. Wie bei den meisten Linux-Befehlen, steckt mehr dahinter, als man denkt. Wenn Sie jedoch seine Funktionsweise verstehen, können Sie Ihre tägliche Arbeit mit der Linux-Kommandozeile verbessern. Es ist eine lohnende Investition Ihrer Zeit. Es gibt effizientere Wege, den Verlauf zu nutzen, als nur wiederholt die Pfeiltaste nach oben zu drücken.
Der Befehl `history`
In seiner einfachsten Form wird der Befehl `history` durch Eingabe seines Namens aufgerufen:
history
Daraufhin wird eine Liste der zuletzt ausgeführten Befehle im Terminalfenster angezeigt.
Die Befehle sind nummeriert, wobei die zuletzt ausgeführten (mit den höchsten Nummern) am Ende der Liste stehen.
Um eine bestimmte Anzahl von Befehlen anzuzeigen, kann man eine Zahl an den `history`-Befehl übergeben. Um beispielsweise die letzten 10 Befehle anzuzeigen, geben Sie Folgendes ein:
history 10
Das gleiche Ergebnis lässt sich auch mit dem `tail`-Befehl erzielen. Geben Sie dazu Folgendes ein:
history | tail -n 10
Befehle wiederholen
Um einen Befehl aus der Verlaufsliste wiederzuverwenden, geben Sie ein Ausrufezeichen (!) gefolgt von der Nummer des Befehls ein, ohne Leerzeichen dazwischen.
Um beispielsweise den Befehl Nummer 37 zu wiederholen, geben Sie ein:
!37
Um den letzten Befehl zu wiederholen, verwenden Sie zwei Ausrufezeichen ohne Leerzeichen:
!!
Dies ist nützlich, wenn Sie einen Befehl ausführen und vergessen, `sudo` zu verwenden. Geben Sie `sudo`, ein Leerzeichen und dann `!!` ein und drücken Sie Enter.
Im folgenden Beispiel haben wir einen Befehl eingegeben, der `sudo` benötigt. Anstatt die gesamte Zeile neu einzugeben, können wir uns einige Tastenanschläge sparen und einfach `sudo !!` eingeben, wie unten gezeigt:
mv ./my_script.sh /usr/local/bin/
sudo !!
Sie können also die entsprechende Zahl aus der Liste eingeben, um einen Befehl zu wiederholen, oder `!!` um den letzten Befehl zu verwenden. Was aber, wenn Sie den fünften oder achten Befehl wiederholen möchten?
Sie können ein Ausrufezeichen, einen Bindestrich (-) und die Nummer eines vorherigen Befehls (wieder ohne Leerzeichen) verwenden, um ihn zu wiederholen.
Um den 13. vorherigen Befehl zu wiederholen, geben Sie ein:
!-13
Befehle nach Zeichenfolge suchen
Um den letzten Befehl zu wiederholen, der mit einer bestimmten Zeichenfolge beginnt, geben Sie ein Ausrufezeichen und dann die Zeichenfolge ohne Leerzeichen ein und drücken Sie Enter.
Um beispielsweise den letzten Befehl zu wiederholen, der mit `sudo` begann, geben Sie diesen Befehl ein:
!sudo
Hier liegt jedoch ein Risiko. Wenn der letzte Befehl, der mit `sudo` gestartet wurde, nicht der ist, den Sie erwarten, führen Sie den falschen Befehl aus.
Um dies zu verhindern, können Sie den Modifikator `:p` (print) verwenden, wie unten gezeigt:
!sudo:p
Dadurch wird der Befehl im Terminalfenster angezeigt, anstatt ihn auszuführen. Auf diese Weise können Sie den Befehl sehen, bevor Sie ihn verwenden. Wenn es der gewünschte Befehl ist, drücken Sie die Pfeiltaste nach oben und dann Enter, um ihn auszuführen.
Um einen Befehl zu suchen, der eine bestimmte Zeichenfolge enthält, können Sie ein Ausrufezeichen und ein Fragezeichen verwenden.
Um beispielsweise den ersten passenden Befehl zu finden und auszuführen, der das Wort „aliases“ enthält, geben Sie diesen Befehl ein:
!?aliases
Dies findet jeden Befehl, der die Zeichenfolge „aliases“ enthält, unabhängig davon, wo sie in der Zeichenfolge vorkommt.
Interaktive Suche
Eine interaktive Suche ermöglicht es Ihnen, durch eine Liste passender Befehle zu springen und den gewünschten Befehl auszuwählen.
Drücken Sie einfach Strg+r, um die Suche zu starten.
Während Sie den Suchbegriff eingeben, wird der erste passende Befehl angezeigt. Die von Ihnen eingegebenen Buchstaben erscheinen zwischen dem Backtick (`) und dem Apostroph (´). Die entsprechenden Befehle werden aktualisiert, während Sie jeden Buchstaben eingeben.
Jedes Mal, wenn Sie Strg+r drücken, wird rückwärts nach dem nächsten passenden Befehl gesucht, der im Terminalfenster angezeigt wird.
Wenn Sie Enter drücken, wird der angezeigte Befehl ausgeführt.
Um einen Befehl vor der Ausführung zu bearbeiten, drücken Sie entweder die linke oder die rechte Pfeiltaste.
Der Befehl wird in der Befehlszeile angezeigt und kann bearbeitet werden.
Sie können auch andere Linux-Tools verwenden, um die Verlaufsliste zu durchsuchen. Um beispielsweise die Ausgabe von `history` an `grep` zu leiten und nach Befehlen zu suchen, die die Zeichenfolge „aliases“ enthalten, können Sie diesen Befehl verwenden:
history | grep aliases
Den letzten Befehl modifizieren
Wenn Sie einen Tippfehler korrigieren und den Befehl dann wiederholen möchten, können Sie ihn mit dem Caret-Zeichen (^) ändern. Dies ist ein nützlicher Trick, wenn Sie einen Befehl falsch geschrieben haben oder ihn mit einer anderen Option oder einem anderen Parameter erneut ausführen möchten.
Um ihn zu verwenden, geben Sie (ohne Leerzeichen) ein Caret-Zeichen, den zu ersetzenden Text, ein weiteres Caret-Zeichen, den neuen Text, ein weiteres Caret-Zeichen ein und drücken Sie Enter.
Angenommen, Sie geben folgenden Befehl ein und geben versehentlich „shhd“ anstelle von „sshd“ ein:
sudo systemctl start shhd
Sie können dies einfach korrigieren, indem Sie Folgendes eingeben:
^shhd^sshd^
Der Befehl wird mit „shhd“ durch „sshd“ korrigiert ausgeführt.
Befehle aus der Verlaufsliste löschen
Sie können Befehle auch mit der Option `-d` (delete) aus der Verlaufsliste löschen. Es gibt keinen Grund, Ihren falsch geschriebenen Befehl in der Liste zu behalten.
Sie können `grep` verwenden, um ihn zu finden, seine Nummer mit der Option `-d` an `history` übergeben, um ihn zu löschen, und dann erneut suchen, um sicherzustellen, dass er entfernt wurde:
history | grep shhd
history -d 83
history | grep shhd
Sie können auch eine Reihe von Befehlen an die Option `-d` übergeben. Um alle Listeneinträge von 22 bis 32 (einschließlich) zu löschen, geben Sie folgenden Befehl ein:
history -d 22 32
Um nur die letzten fünf Befehle zu löschen, können Sie eine negative Zahl wie folgt eingeben:
history -d -5
Manuelles Aktualisieren der Verlaufsdatei
Wenn Sie sich anmelden oder eine Terminalsitzung öffnen, wird die Verlaufsliste aus der Verlaufsdatei gelesen. In Bash ist die Standardverlaufsdatei `.bash_history`.
Alle Änderungen, die Sie in Ihrer aktuellen Terminalsitzung vornehmen, werden erst in die Verlaufsdatei geschrieben, wenn Sie das Terminalfenster schließen oder sich abmelden.
Angenommen, Sie möchten ein weiteres Terminalfenster öffnen, um auf die vollständige Verlaufsliste zuzugreifen, einschließlich der Befehle, die Sie im ersten Fenster eingegeben haben. Mit der Option `-a` (all) können Sie dies im ersten Terminalfenster tun, bevor Sie das zweite öffnen.
Geben Sie Folgendes ein, um es zu verwenden:
history -a
Die Befehle werden stillschweigend in die Verlaufsdatei geschrieben.
Wenn Sie alle Änderungen an der Verlaufsliste in die Verlaufsdatei schreiben möchten (z. B. wenn Sie einige alte Befehle gelöscht haben), können Sie die Option `-w` (write) verwenden, wie folgt:
history -w
Löschen der Verlaufsliste
Um alle Befehle aus der Verlaufsliste zu löschen, können Sie die Option `-c` (clear) wie folgt verwenden:
history -c
Wenn Sie diese Änderungen zusätzlich in der Verlaufsdatei erzwingen möchten, verwenden Sie die Option `-w` wie folgt:
history -w
Sicherheit und die Verlaufsdatei
Wenn Sie Anwendungen verwenden, bei denen Sie sensible Daten (wie Passwörter) in die Befehlszeile eingeben müssen, denken Sie daran, dass diese auch in der Verlaufsdatei gespeichert werden. Um bestimmte Informationen nicht zu speichern, können Sie diese mit folgender Befehlsstruktur sofort aus der Verlaufsliste löschen:
special-app my-secret-password;history -d $(history 1)
history 5
Diese Struktur enthält zwei Befehle, die durch ein Semikolon (;) getrennt sind. Hier die Aufschlüsselung:
`special-app`: Der Name des verwendeten Programms.
`my-secret-password`: Das geheime Passwort, das für die Anwendung in der Kommandozeile erforderlich ist. Dies ist das Ende des ersten Befehls.
`history -d`: Im zweiten Befehl wird die Option `-d` (delete) von `history` aufgerufen. Was gelöscht wird, steht im nächsten Teil des Befehls.
`$(history 1)`: Dies verwendet eine Befehlssubstitution. Der in `$( )` enthaltene Teil wird in einer Subshell ausgeführt. Das Ergebnis dieser Ausführung wird als Text im ursprünglichen Befehl angezeigt. Der Befehl `history 1` gibt den vorherigen Befehl zurück. Man kann sich den zweiten Befehl also als `history -d „letzter Befehl“` vorstellen.
Sie können den Befehl `history 5` verwenden, um sicherzustellen, dass der Befehl mit dem Passwort aus der Verlaufsliste entfernt wurde.
Es gibt jedoch einen noch einfacheren Weg: Da Bash standardmäßig Zeilen ignoriert, die mit einem Leerzeichen beginnen, fügen Sie einfach ein Leerzeichen am Anfang der Zeile ein, wie folgt:
special-app another-password
history 5
Der Befehl mit dem Passwort wird nicht zur Verlaufsliste hinzugefügt. Der Grund dafür liegt in der Datei `.bashrc`.
Die `.bashrc`-Datei
Die Datei `.bashrc` wird jedes Mal ausgeführt, wenn Sie sich anmelden oder ein Terminalfenster öffnen. Sie enthält auch einige Werte, die das Verhalten des `history`-Befehls steuern. Lassen Sie uns diese Datei mit `gedit` bearbeiten.
Geben Sie ein:
gedit .bashrc
Oben in der Datei sehen Sie zwei Einträge:
`HISTSIZE`: Die maximale Anzahl von Einträgen, die die Verlaufsliste enthalten kann.
`HISTFILESIZE`: Die maximale Anzahl von Zeilen, die eine Verlaufsdatei enthalten kann.
Diese beiden Werte interagieren wie folgt:
Beim Anmelden oder Starten einer Terminalfenstersitzung wird die Verlaufsliste aus der Datei `.bash_history` geladen. |
Wenn Sie ein Terminalfenster schließen, wird die in `HISTSIZE` festgelegte maximale Anzahl von Befehlen in der Datei `.bash_history` gespeichert. |
Wenn die Shell-Option `histappend` aktiviert ist, werden die Befehle an `.bash_history` angehängt. Wenn `histappend` nicht gesetzt ist, wird `.bash_history` überschrieben. |
Nach dem Speichern der Befehle aus der Verlaufsliste in `.bash_history` wird die Verlaufsdatei gekürzt, sodass sie nicht mehr als `HISTFILESIZE` Zeilen enthält. |
Außerdem sehen Sie oben in der Datei einen Eintrag für den `HISTCONTROL`-Wert.
Sie können diesen Wert auf eine der folgenden Optionen setzen:
`ignorespaces`: Zeilen, die mit einem Leerzeichen beginnen, werden der Verlaufsliste nicht hinzugefügt.
`ignoredups`: Doppelte Befehle werden der Verlaufsdatei nicht hinzugefügt.
`ignoreboth`: Aktiviert beide Optionen.
Sie können auch bestimmte Befehle auflisten, die nicht zu Ihrer Verlaufsliste hinzugefügt werden sollen. Trennen Sie diese mit einem Doppelpunkt (:) und setzen Sie sie in Anführungszeichen („…“)
Sie würden dieser Struktur folgen, um Ihrer `.bashrc`-Datei eine Zeile hinzuzufügen und die zu ignorierenden Befehle zu ersetzen:
export HISTIGNORE="ls:history"
Verwendung von Zeitstempeln
Wenn Sie der Verlaufsliste Zeitstempel hinzufügen möchten, können Sie die Einstellung `HISTTIMEFORMAT` verwenden. Fügen Sie einfach eine Zeile wie die folgende zu Ihrer `.bashrc`-Datei hinzu:
export HISTTIMEFORMAT="%c "
Beachten Sie, dass vor dem schließenden Anführungszeichen ein Leerzeichen steht. Dies verhindert, dass der Zeitstempel an die Befehle in der Befehlsliste angrenzt.
Wenn Sie nun den Befehl `history` ausführen, sehen Sie Datums- und Zeitstempel. Beachten Sie, dass alle Befehle, die sich vor dem Hinzufügen der Zeitstempel in der Verlaufsliste befanden, mit dem Datum und der Uhrzeit des ersten Befehls versehen werden, der einen Zeitstempel erhält. In dem hier gezeigten Beispiel war dies Befehl 118.
Das ist ein sehr ausführlicher Zeitstempel. Sie können jedoch andere Token als `%c` verwenden, um ihn zu verfeinern. Die anderen Token, die Sie verwenden können, sind:
`%d`: Tag
`%m`: Monat
`%y`: Jahr
`%H`: Stunde
`%M`: Minuten
`%S`: Sekunden
`%F`: Vollständiges Datum (Jahr-Monat-Tag-Format)
`%T`: Zeit (Stunde:Minute:Sekunde-Format)
`%c`: Vollständiger Datums- und Zeitstempel (Tag-Datum-Monat-Jahr und Stunde:Minute:Sekunde-Formate)
Lassen Sie uns experimentieren und ein paar verschiedene Token verwenden:
export HISTTIMEFORMAT="%d n%m %T "
Die Ausgabe verwendet Tag, Monat und Uhrzeit.
Wenn wir jedoch Tag und Monat entfernen, wird nur die Uhrzeit angezeigt.
Alle Änderungen, die Sie an `HISTTIMEFORMAT` vornehmen, gelten für die gesamte Verlaufsliste. Dies ist möglich, da die Uhrzeit für jeden Befehl als Anzahl der Sekunden seit der Unix-Epoche gespeichert wird. Die `HISTTIMEFORMAT`-Direktive gibt lediglich das Format an, das verwendet wird, um diese Anzahl von Sekunden in einen für Menschen lesbaren Stil zu rendern, z. B.:
export HISTTIMEFORMAT="%T "
Unsere Ausgabe ist nun übersichtlicher.
Sie können den Befehl `history` auch zur Überprüfung verwenden. Manchmal kann es helfen, zu überprüfen, welche Befehle Sie in der Vergangenheit verwendet haben, um herauszufinden, was ein Problem verursacht haben könnte.
Genau wie im Leben können Sie unter Linux den Befehl `history` verwenden, um gute Zeiten noch einmal zu erleben und aus schlechten zu lernen.