Wie kann ich die Bash-Historie durchsuchen und einen Befehl erneut ausführen?

157555
Richard Hoskins

Kann ich den Verlauf in bash durchsuchen und das Ergebnis ausführen?

279

10 Antworten auf die Frage

403
Sean Bright

Geben Sie Ctrl Rin die Befehlszeile ein und geben Sie den vorherigen Befehl ein. Sobald ein Ergebnis angezeigt wird, können Ctrl RSie weitere Treffer anzeigen. Wenn der gewünschte Befehl angezeigt wird, drücken Sie einfachEnter

Beachten Sie, dass while Ctrl Rdie Standardeinstellung ist, wenn Sie den Befehl ( reverse-search-history) an sich gebunden haben Ctrl Tmöchten, dies mit folgendem Befehl konfigurieren könnte:

'' \ Ct 'binden: Reverse-Search-History' 

Es gibt eine ganze Reihe weiterer readline-bindbarer Befehle, die Ihnen ebenfalls zur Verfügung stehen. Schauen Sie sich die bashManpage an .

Bash bietet viele Möglichkeiten zum Suchen und Aufrufen des interaktiven Befehlsverlaufs. Das grundlegendste davon ist das historyeingebaute. Tippen Sie einfach:

$ Geschichte 

Druckt eine Liste von Befehlen zusammen mit einem numerischen Index aus:

$ Geschichte 1 klar 2 ls -al 3 vim ~ / somefile.txt 4 geschichte $ 

Sie können dann jeden dieser Befehle mit ihrem numerischen Index ausführen, indem Sie den Index mit einem einzigen Befehl voranstellen !, wie Mitch darauf hingewiesen hat:

$! 1 

Führt den clearBefehl aus. Die Geschichte builtin hat viele Funktionen selbst, Sie mehr in der sehen bashund historyman - Seiten.

Sie können auch relative negative Offsets angeben, wenn Sie den !Bezeichner verwenden. Wenn Sie unsere Verlaufsliste verwenden möchten, können Sie Folgendes ausführen vim:

$! -2 

Dies bedeutet im Grunde, dass bash den Befehl ausführen soll, den Sie "vor zwei Befehlen" ausgeführt haben. Um den vorherigen Befehl in der Verlaufsliste auszuführen, können wir einfach !!(was nur eine Kurzform ist !-1) verwenden.

Der !Bezeichner beschränkt Sie nicht auf die numerische Angabe des auszuführenden Befehls. hayalci hat gezeigt, dass Sie die bashAusführung eines Befehls anweisen können, basierend auf dem Text, mit dem er beginnt (using !) oder dem Text innerhalb des Befehls selbst (using !?). Wenn wir clearerneut unsere Beispielhistorienliste verwenden möchten, müssen wir nur noch Folgendes ausführen :

$! cl 

und drücken Sie Enter. Und was ist mit vim? Das ist so einfach wie:

$!? einige 

Der wichtigste Punkt aus der Antwort von hayalci ist der Aufruf an das shoptBuiltin:

$ shopt -s histverify 

Dadurch wird die Verlaufsüberprüfung aktiviert, sodass Befehle, die von,, und Bezeichnern abgeglichen werden !, nicht blind ausgeführt werden, sondern stattdessen in der Befehlszeile ausgefüllt werden, sodass Sie sicherstellen können, dass sie vor der Ausführung nichts Böses tun. Dies ist umso wichtiger, wenn Sie als Root-Benutzer Befehle ausführen. Diese Option kann in Ihrer Startdatei so festgelegt werden, dass sie bei jeder Anmeldung festgelegt wird.!!!?.bashrc

Wie bereits erwähnt, können alle diese Informationen aus der bashManpage entnommen werden . Für die!, !! und!? Bezeichner finden Sie in Abschnitt 9.3 History Expansion .

+1 Ich benutze Linux seit über 12 Jahren für alle Systeme. Ich wusste nicht, dass es existiert. Wünschte, ich könnte +10 * Wie habe ich es vermisst? * Aiden Bell vor 14 Jahren 35
Ich habe es erst entdeckt, als ich regelmäßig mit Emacs angefangen habe. Dann habe ich es eines Tages aus Versehen in Bash getippt (ich dachte, ich wäre in Emacs). Sean Bright vor 14 Jahren 0
Bei vielen Systemen funktioniert das Drücken des Aufwärtspfeils genauso. mas vor 14 Jahren 1
Der Aufwärtspfeil geht für mich einfach zum vorherigen Befehl. Aber ja, es ist an alles gebunden, was Sie wollen. Sean Bright vor 14 Jahren 3
Wenn jemand "!", "!!", "!?", "Geschichte | grep 'und' ctrl-r 'zu einer umfassenden Antwort, würde ich sie auswählen Richard Hoskins vor 14 Jahren 0
@richardhoskins - fertig. Sean Bright vor 14 Jahren 0
`shopt` geht in bashrc, nicht in bash_profile (oder wird nicht für Shells aktiviert, die keine Login-Shells sind). Tobu vor 13 Jahren 0
Nach dem Drücken von STRG + R können Sie auch mehrmals STRG + UMSCHALT + R verwenden, um zum vorherigen Befehl zurückzukehren Gal Bracha vor 8 Jahren 2
Sie können auch `!!` ausführen, um den vorherigen Befehl auszuführen. Zum Beispiel `sudo !!`, um den vorherigen Befehl mit sudo auszuführen. sotoz vor 7 Jahren 0
35
hayalci

Alternativ dazu crtl+Rkönnen Sie den Verlauf durch Eingabe durchsuchen

!text 

Dadurch wird der Verlauf nach dem neuesten Befehl durchsucht, der mit "Text" beginnt .

Aber ich schlage vor, Sie setzen dies in Ihre .bashrc, um die Ausführung eines falschen Befehls zu verhindern.

shopt -s histverify 

Dadurch wird bash so angewiesen, dass nach etwaigen Verlaufsaktionen (wie !!:s/prev_text/after_text) die resultierende Zeile an der Eingabeaufforderung platziert wird. Dann können Sie den Befehl überprüfen oder bearbeiten und anschließend die Eingabetaste drücken.

Verwenden Sie!? - Text, um den neuesten Befehl erneut auszuführen, der (im Gegensatz zum Anfang) "Text" enthält. mark4o vor 14 Jahren 5
Wenn jemand "!", "!!", "!?", "Geschichte | grep 'und' ctrl-r 'zu einer umfassenden Antwort, würde ich sie auswählen. Richard Hoskins vor 14 Jahren 3
29
Mitch

Sie könnten auch tun:

history | grep "stuff" 

es würde so etwas zurückgeben

num stuff 

dann kannst du tippen

!num 
14
Keith

Ich ziehe es vor, die History-Suche rückwärts über die Rückwärtssuche zu verwenden. Beim ersteren können Sie einige Zeichen des Befehls eingeben und dann die Suchtaste drücken, anstatt zuerst die Suchtaste zu drücken und dann die Suchzeichenfolge einzugeben.

Auf meinem System sind Mp und Mn standardmäßig an ähnliche Funktionen gebunden, ich ziehe es jedoch vor, die Pfeiltasten zu binden:

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

Hervorragendes Schreiben, Sean! Ich würde dies in einem Kommentar einfügen, aber ich bin ein paar Rufpunkte schüchtern. :-)

Eine weitere verwandte und nützliche Technik ist die Möglichkeit, einen vorherigen Befehl auszuführen, während ein Wort geändert wird. Angenommen, Sie haben den Verzeichnisnamen getippt oder möchten den Dateinamen ändern:

$ echo mein name ist bob mein Name ist Bob $ ^ bob ^ Jordan Echo, mein Name ist Jordan Mein Name ist Jordan

Beachten Sie, dass der Befehl erweitert, ersetzt und ausgegeben wird, bevor der Befehl ausgeführt wird. Wenn also der falsche Befehl ausgeführt wird, können Sie sehen, was der Bash dachte.

12
CurtH

Ich habe ein wirklich tolles Alias, h. Es ist wirklich nur "history | grep", aber ich filtere vorherige "h command" -Einträge mit "grep -E -v" aus.

alias h="history | grep -E -v '^ *[0-9]+ *h ' | grep " 

verwendet wie

h aliases 2003 less .bash_aliases 
Dies kann auch durch Hinzufügen des Befehls zu "HISTIGNORE" erreicht werden. tanenbring vor 6 Jahren 0
5
Martin Dvorak

Da die Navigation durch den Verlauf mit Strg-r IMO umständlich ist, sollten Sie hh in Betracht ziehen :

https://github.com/dvorka/hstr

was die Navigation wesentlich einfacher, unkomplizierter und effizienter macht - einschließlich der Ausführung des Befehls:

enter image description here

Wie benutze ich es? Welche Tasten müssen gedrückt werden, um dieses Bild zu sehen? Nakilon vor 9 Jahren 0
Nachdem Sie hh installiert haben, können Sie entweder den Befehl hh verwenden oder ihn an eine beliebige Tastenkombination (normalerweise Strg-r) binden, wie in der Dokumentation beschrieben. Martin Dvorak vor 9 Jahren 2
Es bindet sich jetzt standardmäßig an `ctrl + r` Alleo vor 6 Jahren 0
3
John1024

Geben Sie an der Bash-Eingabeaufforderung control-R ein. Geben Sie dann einige Zeichen des gewünschten Befehls ein. Die Readline-Funktion von bash durchsucht den Befehlsprotokoll nach diesem Befehl.

Nachdem Sie die Suche gestartet haben, können Sie erneut control-R eingeben, um zum nächsten passenden Befehl zu springen.

3
Fernando Basso

Wenn Sie Ihre Shell konfigurieren verwenden viTastenbelegungen ( set -o vioder mit set editing-mode viin $HOME/.inputrc), dann suchen Sie mit <Esc>/some-command<Return>und schlagen n(nächste) oder Shift-n(zurück), um durch die Geschichte Kommandozeile.

Dies ist der vim-Benutzer am nächsten. Gabor Marton vor 6 Jahren 0
2
Mureinik

CTRL+ Rfunktioniert gut, wie @ John1024 vorgeschlagen, ist aber etwas langweilig, wenn viele Ihrer letzten Befehle ähnlich sind und Sie einen schnellen Weg suchen, um alle zu scannen. Eine Alternative wäre zu verwenden history:

$ history | grep keyword