it-swarm.com.de

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

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

288
Richard Hoskins

Art CtrlR Geben Sie in der Befehlszeile den vorherigen Befehl ein. Sobald ein Ergebnis erscheint, schlagen Sie weiter CtrlR um andere Übereinstimmungen zu sehen. Wenn der gewünschte Befehl angezeigt wird, drücken Sie einfach Enter

Beachten Sie, dass während CtrlR ist die Standardeinstellung, wenn der Befehl (reverse-search-history) gebunden werden soll CtrlT Sie können das folgendermaßen konfigurieren:

 bind '"\ C-t": Reverse-Search-History' 

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

Bash verfügt über zahlreiche Funktionen zum Suchen und Zugreifen auf den interaktiven Befehlsverlauf. Der grundlegendste davon ist der history. Tippen Sie einfach:

 $ Geschichte 

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

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

Sie können dann jeden dieser Befehle unter Verwendung des numerischen Index ausführen, indem Sie dem Index einen einzelnen ! voranstellen, wie in Mitch angegeben:

 $! 1 

Führt den Befehl clear aus. Die integrierte Historie hat viele Funktionen. Weitere Informationen finden Sie auf den Manpages bash und history.

Sie können auch relative negative Offsets angeben, wenn Sie den Bezeichner ! verwenden. Wenn wir also vim in der Verlaufsliste oben erneut 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 Sie einfach !! verwenden (was nur eine Abkürzung für !-1 ist).

Mit dem Bezeichner ! können Sie nicht nur numerisch angeben, welcher Befehl ausgeführt werden soll. hayalci hat gezeigt, dass Sie bash anweisen können, einen Befehl auszuführen, der entweder auf dem Text basiert, mit dem er beginnt (mit !), oder auf dem Text im Befehl selbst (mit !?). Um clear erneut auszuführen, müssen wir in der obigen Beispielverlaufsliste nur Folgendes eingeben:

 $! cl 

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

 $!? einige 

Der wichtigste Punkt in der Antwort von hayalci ist der Aufruf der eingebauten shopt:

 $ shopt -s histverifizieren 

Dadurch wird die Verlaufsüberprüfung aktiviert, sodass Befehle, die mit den Bezeichnern !, !! und !? übereinstimmen, nicht blind ausgeführt werden, 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 .bashrc festgelegt werden, sodass sie bei jeder Anmeldung festgelegt wird.

Wie bereits erwähnt, können alle diese Informationen aus der Manpage bash entnommen werden. Für die!, !! und!? Bezeichner, werfen Sie einen Blick auf Abschnitt 9.3 History Expansion .

421
Sean Bright

Als Alternative zu 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 an, dass nach any history-Aktionen (wie !!:s/prev_text/after_text) die resultierende Zeile an den Befehl Prompt angehängt wird. Anschließend können Sie den Befehl überprüfen oder bearbeiten und anschließend die Eingabetaste drücken.

36
hayalci

Sie könnten auch tun:

history | grep "stuff"

es würde so etwas wie zurückgeben

num stuff

dann kannst du tippen

!num
30
Mitch

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

Standardmäßig binden M-p und M-n auf meinem System an ähnliche Funktionen, aber ich bevorzuge es, die Pfeiltasten zu binden:

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

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
12
CurtH

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 Word geändert wird. Angenommen, Sie haben den Verzeichnisnamen eingegeben 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 Bash gedacht hat.

12
Jordan

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

https://github.com/dvorka/hstr

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

enter image description here

5
Martin Dvorak

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

Wenn Ihre Shell so konfiguriert ist, dass sie vi Tastenzuordnungen verwendet (set -o vi oder set editing-mode vi in $HOME/.inputrc), suchen Sie mit <Esc>/some-command<Return> und drücken n (next) oder Shift-n (previous), um durch den Befehlszeilenverlauf zu blättern.

3
Fernando Basso

CTRL+R Funktioniert 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 historyNAME _ zu verwenden:

$ history | grep keyword
2
Mureinik