Wie kann ich den Bash-Verlauf durchsuchen und einen Befehl erneut ausführen?


297

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

Antworten:


428

Geben Sie Ctrl Rin die Befehlszeile ein und beginnen Sie mit der Eingabe des vorherigen Befehls. Sobald ein Ergebnis angezeigt wird, drücken Sie die Taste Ctrl R, um weitere Übereinstimmungen anzuzeigen. Wenn der gewünschte Befehl angezeigt wird, drücken Sie einfachEnter

Beachten Sie, dass while Ctrl Rdie Standardeinstellung ist, wenn Sie möchten, dass der Befehl ( reverse-search-history) an Ctrl TFolgendes gebunden wird :

Bind '"\ Ct": 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 verfügt über zahlreiche Funktionen zum Suchen und Zugreifen auf den interaktiven Befehlsverlauf. Das grundlegendste davon ist das historyeingebaute. Tippen Sie einfach:

$ history

Gibt eine Liste von Befehlen zusammen mit einem numerischen Index aus, wie zum Beispiel:

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

Sie können dann jeden dieser Befehle unter Verwendung des numerischen Index ausführen, indem Sie dem Index eine einzelne voranstellen !, wie Mitch ausführte:

$! 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 wir also unsere Verlaufsliste oben vimerneut ausführen möchten, können wir Folgendes tun:

$! -2

Das bedeutet, 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 verwenden !!(was nur eine Abkürzung für ist !-1).

Der !Bezeichner beschränkt sich nicht auf die numerische Angabe des auszuführenden Befehls. hayalci hat gezeigt, dass Sie anweisen können bash, einen Befehl basierend auf dem Text auszuführen, mit dem er beginnt (using !), oder basierend auf dem Text im Befehl selbst (using !?). Unter Verwendung der obigen Beispielverlaufsliste müssen wir nur Folgendes eingeben, wenn wir clearerneut ausführen möchten:

$! cl

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

$!? einige

Der wichtigste Punkt in Hayalcis Antwort ist der Aufruf an das shopteingebaute System:

$ shopt -s histverifizieren

Auf diese Weise wird die Verlaufsüberprüfung aktiviert, sodass Befehle, die mit dem,, und den Bezeichnern übereinstimmen !, nicht blind ausgeführt, sondern in der Befehlszeile eingegeben werden, damit 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 festgelegt werden, sodass 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, Verlaufserweiterung .


39
+1 Ich benutze Linux seit über 12 Jahren für alle Systeme. Ich wusste nicht, dass es das gibt. Ich wünschte, ich könnte +10, wie habe ich es vermisst?
Aiden Bell

1
Bei vielen Systemen wird das gleiche durch Drücken des Aufwärtspfeils erreicht.
mas

Wenn jemand '!', '!!', '!?', 'History | grep 'und' ctrl-r 'in eine umfassende Antwort, ich würde es auswählen
Richard Hoskins

shoptGeht in bashrc, nicht in bash_profile (oder wird nicht für Shells aktiviert, die keine Login-Shells sind).
Tobu

2
Auch nach Drücken von STRG + R können Sie STRG + UMSCHALT + R mehrmals verwenden, um zum vorherigen Befehl zurückzukehren
Gal Bracha

37

Alternativ dazu crtl+Rkönnen Sie den Verlauf durchsuchen, indem Sie Folgendes eingeben

!text

Dadurch wird der Verlauf nach dem neuesten Befehl durchsucht, der mit 'text' beginnt .

Aber ich schlage vor, Sie fügen dies in Ihre .bashrc-Datei ein, um die Ausführung eines falschen Befehls zu verhindern.

shopt -s histverify

Dies weist bash , so dass nach irgendwelchen Geschichte Aktionen (wie !!:s/prev_text/after_text), ist es die resultierende Zeile der Eingabeaufforderung stellt. Anschließend können Sie den Befehl überprüfen oder bearbeiten und anschließend die Eingabetaste drücken.


5
Verwenden Sie!? Text, um den letzten Befehl erneut auszuführen, der (im Gegensatz zum Beginnen mit) "text" enthält.
mark4o

3
Wenn jemand '!', '!!', '!?', 'History | grep 'und' ctrl-r 'in eine umfassende Antwort, würde ich es auswählen.
Richard Hoskins

32

Sie könnten auch tun:

history | grep "stuff"

es würde so etwas wie zurückgeben

num stuff

dann kannst du tippen

!num

15

Ich bevorzuge es, History-Search-Backward gegenüber Reverse-Search-History zu verwenden. Ersteres lässt Sie ein paar Zeichen des Befehls eingeben und dann die Suchtaste drücken, anstatt zuerst die Suchtaste zu drücken und dann die Suchzeichenfolge einzugeben.

Standardmäßig binden Mp und Mn auf meinem System an ähnliche Funktionen, aber ich bevorzuge das Binden der Pfeiltasten:

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

13

Ich habe einen wirklich tollen 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 "

gebraucht wie

h aliases
2003  less .bash_aliases

1
Dies kann auch durch Hinzufügen des Befehls zu erfolgen HISTIGNORE.
Tanenbring

12

Hervorragender Bericht, Sean! Ich würde das in einen Kommentar schreiben, aber ich bin ein paar Rufpunkte schüchtern. :-)

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

Ich heiße 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 Bash gedacht hat.


6

Da die Navigation durch den Verlauf mit Strg-R IMO umständlich ist, sollten Sie Folgendes berücksichtigen :

https://github.com/dvorka/hstr

Dies macht die Navigation viel einfacher, einfacher und effizienter - einschließlich der Ausführung des Befehls:

Bildbeschreibung hier eingeben


Wie benutzt man es? Welche Tasten müssen gedrückt werden, um dieses Bild zu sehen?
Nakilon,

2
Sobald 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

es bindet sich ctrl + rjetzt standardmäßig an
Alleo

4

Geben Sie an der Bash-Eingabeaufforderung control-R ein und geben Sie dann einige Zeichen des gewünschten Befehls ein. Die Readline-Funktion von Bash durchsucht den Befehlsverlauf 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

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.


Dieser ist den vim-Benutzern am nächsten.
Gabor Marton

2

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

$ history | grep keyword

0

Ich mag HSTR, aber ich kann es manchmal nicht installieren. Also habe ich einen Alias ​​mit fzf geschrieben, der sein Verhalten nachahmt ( hxfür "history execute ")

alias hx='eval $(history | sed "s/^ *[0-9]* *//g" | fzf --tac --tiebreak=index --height=10)'
  • history : Nun, holen Sie sich die Geschichte
  • sed : Entferne die Nummernspalte aus der Liste (POSIX)
  • fzf: Hier ist die Magie: Ermöglicht die interaktive Fuzzy-Suche in der Liste oder das Bewegen mit C-Jund C-KAusführen eines Befehls mit Enter.
  • --height : Stellen Sie die Anzahl der angezeigten Zeilen ein.
  • --tac : Liste zurücksetzen (logischer für eine Geschichte)
  • --tiebreak=index : Behalte die Verlaufsreihenfolge, wenn FZF die Ergebnisse aktualisiert
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.