Verwenden Sie den Bash-Verlauf, um einen vorherigen Befehl abzurufen, kopieren Sie ihn und führen Sie ihn dann aus, wobei der Befehl kommentiert ist

79

Nur eine Frage, um meine bashFähigkeiten zu verbessern . Ich mache immer das:

$ history | grep some_long_command

...
...
123 some_long_command1.........
124 some_long_command2.........
...

Ich kann dann den Befehl ausführen, den ich gefunden habe, indem ich Folgendes getan habe:

!123

Ich möchte dies jedoch häufig tun:

some_long_command1foobar

Dh den Befehl ändern, bevor ich ihn ausführe. Können Sie stattdessen bash verwenden, um diesen Befehl auszuführen:

#some_long_command1

so wird es kommentiert.

Dann muss ich den Befehl nicht mit der Maus markieren, bearbeiten und dann ausführen (ich kann einfach die Tastatur verwenden - schneller).

Ich nehme an, ich könnte ein Skript schreiben, um das zu tun, aber irgendwo sind möglicherweise bereits Funktionen eingebaut ...?

Ale
quelle
6
Der einfachste Weg: Fügen Sie bind Space:magic-spaceIhr Bash-Profil ein. Dann drücken Spaceexpandiert !123in some_long_command1.
Blaz
@courteous: Danke! Dieser war neu für mich. Sehr hilfreich.
Marlar

Antworten:

140

Ich würde vorschlagen, anstatt den Befehl history zu verwenden, diesen Befehl zu verwenden ctrl+rund zu schreiben. Wenn Sie eine Pfeiltaste drücken, um sie zu ändern, wird die Erkennung der automatischen Vervollständigung unterbrochen und Sie können sie vor dem Ausführen bearbeiten.

UPDATE: Wenn Sie die verschiedenen Befehle durchlaufen möchten, die die gerade eingegebene Zeichenfolge enthalten, drücken Sie weiter ctrl+r

Miquel
quelle
8
Wenn Sie vi keybindings ( set -o vi) verwenden, können Sie auch /den Verlauf durchsuchen und bearbeiten.
William Pursell
1
Eine leistungsstärkere Funktion ermöglicht das Eingeben eines Teilbefehls oder eines Teils eines Pfads, der sich in einem Befehl befand, und das Navigieren im Verlauf mithilfe der Pfeile. Suche nach Verlauf-Suche-Rückwärts, Verlauf-Suche-Vorwärts-Optionen für Bash
DavidC
2
DavidC, ich habe andere gesehen, aber das funktioniert bei mir nicht. Wenn ich die ersten Buchstaben eines Befehls eingebe und dann den Pfeil nach oben drücke, ignoriert er das, was ich eingegeben habe, und geht durch die Geschichte, als hätte ich überhaupt nichts eingegeben (neueste bis älteste). Wie konfigurieren Sie Ihre Shell, um dies zu erreichen?
Daniel Watrous
1
Es ist traurig, dass das Auf / Ab nicht durch die Übereinstimmungen blättert, sondern die Suche sofort beendet. Ich hätte es vorgezogen, durch die Übereinstimmungen mit Auf / Ab zu scrollen (was anzeigt, dass ich immer noch nach dem gewünschten Befehl suche) und nur links / rechts aus der Suche auszusteigen (was anzeigt, dass ich den gewünschten Befehl gefunden habe und jetzt bin ich bereit, es zu bearbeiten).
ADTC
3
@ADTC Ich habe gerade einen Weg gefunden, um das zu tun, was Sie (und ich) wollen: Drücken Sie ctr+r, beginnen Sie mit der Eingabe. Wenn Sie dann alle Befehle finden möchten, die dies enthalten, drücken Sie einfach weiter ctrl+r. Mit anderen Worten, was Sie mit Auf / Ab machen wollen, wird (in Round-Robin-Manier) mitctrl+r
Miquel
61

Tatsächlich können Sie einfach :pan den Befehl anhängen , um ihn zu drucken, ohne ihn tatsächlich auszuführen. Zum Beispiel:

$ ls -la
$ !!:p

Wird ls -laals vorheriger Befehl ausgedruckt, ohne ihn auszuführen , und Sie können einfach (nach oben) drücken , um ihn zu finden und zu bearbeiten.

Sie können auch tun

!123:p

um den 123. Befehl als Ihren vorherigen Befehl auszudrucken.

joeschmidt45
quelle
2
+1 Die beste Antwort, da die üblichen Verlaufsbefehle das OP beantworten können : !mycmd:p. Wenn Sie vi-Befehle in Bash aktiviert haben, ist Pursells Antwort genauso gut oder besser. Strg-r ist, wie von Miquel erwähnt, der nächstbeste.
Brent Faust
Wenn die 123 nicht am Anfang der Linie steht, können Sie tun:!? 123 ?: P
Udi
19

Sie können auch versuchen fc, den Befehl im Verlauf zu bearbeiten.

WIKI sagt:

FC ist ein Standardprogramm auf Unix , dass Listen oder Editierungen und reexecutes, vorher Befehle an einem interaktiv Shell eingegeben. FC ist ein -in gebaut in dem Befehl bash Shell; help fc zeigt Nutzungsinformationen an.


Abgesehen von der umgekehrten inkrementellen Suche ( Ctrl+ R) gibt es noch einige weitere Bash- Verknüpfungen:

Von man bash:

Vorgeschichte (Cp)
    Rufen Sie den vorherigen Befehl aus der Verlaufsliste ab und kehren Sie in die Liste zurück. 
nächste Geschichte (Cn)
    Rufen Sie den nächsten Befehl aus der Verlaufsliste ab und bewegen Sie sich in der Liste vorwärts. 
Beginn der Geschichte (M- <)
    Gehen Sie zur ersten Zeile im Verlauf. 
Ende der Geschichte (M->)
    Gehen Sie zum Ende des Eingabeverlaufs, dh zur aktuell eingegebenen Zeile. 
Reverse-Search-Historie (Cr)
    Suchen Sie rückwärts, beginnend mit der aktuellen Zeile, und bewegen Sie sich bei Bedarf durch den Verlauf nach oben. Dies ist eine inkrementelle Suche.
Forward-Search-Verlauf (Cs)
    Suchen Sie vorwärts, beginnend mit der aktuellen Zeile, und bewegen Sie sich bei Bedarf nach unten durch den Verlauf. Dies ist eine inkrementelle Suche.
nicht inkrementeller Reverse-Search-Verlauf (Mp)
    Durchsuchen Sie den Verlauf ab der aktuellen Zeile rückwärts, indem Sie nicht inkrementell nach einer vom Benutzer angegebenen Zeichenfolge suchen. 
nicht inkrementelle Vorwärtssuchhistorie (Mn)
    Durchsuchen Sie den Verlauf mit einer nicht inkrementellen Suche nach einer vom Benutzer angegebenen Zeichenfolge.
yank-nth-arg (MCy)
    Fügen Sie das erste Argument an der Stelle in den vorherigen Befehl ein (normalerweise das zweite Wort in der vorherigen Zeile). Fügen Sie mit einem Argument n das n-te Wort aus dem vorherigen Befehl ein (die Wörter im vorherigen Befehl beginnen mit Wort 0). Ein negatives Argument fügt das n-te Wort vom Ende des vorherigen Befehls ein. Sobald das Argument n berechnet wurde, wird das Argument extrahiert, als ob die "! N" -Historieerweiterung angegeben worden wäre.
yank-last-arg (M-., M-_)
    Fügen Sie das letzte Argument in den vorherigen Befehl ein (das letzte Wort des vorherigen Verlaufseintrags). Verhalten Sie sich mit einem Argument genau wie yank-nth-arg. Aufeinanderfolgende Aufrufe von yank-last-arg gehen zurück durch die Verlaufsliste und fügen nacheinander das letzte Argument jeder Zeile ein. Die Verlaufserweiterungsfunktionen werden verwendet, um das letzte Argument zu extrahieren, als ob die "! $" - Verlaufserweiterung angegeben worden wäre.
Shell-Expand-Line (MCe)
    Erweitern Sie die Linie wie die Shell. Dies führt eine Alias- und Verlaufserweiterung sowie alle Shell-Worterweiterungen durch. Unter HISTORY EXPANSION unten finden Sie eine Beschreibung der History-Erweiterung.
History-Expand-Line (M- ^)
    Führen Sie eine Verlaufserweiterung in der aktuellen Zeile durch. Eine Beschreibung der Verlaufserweiterung finden Sie unten unter GESCHICHTSERWEITERUNG.
Einfügen des letzten Arguments (M-., M-_)
    Ein Synonym für yank-last-arg. 
operieren und weiterkommen (Co)
    Akzeptieren Sie die aktuelle Zeile zur Ausführung und rufen Sie die nächste Zeile relativ zur aktuellen Zeile aus dem Verlauf zur Bearbeitung ab. Jedes Argument wird ignoriert.
Befehl zum Bearbeiten und Ausführen (C-xC-e)
    Rufen Sie einen Editor in der aktuellen Befehlszeile auf und führen Sie das Ergebnis als Shell-Befehle aus.
Prinz John Wesley
quelle
11
!123:gs/old/new/

Führt den Befehl 123 aus und ersetzt die Zeichenfolge 'alt' durch die Zeichenfolge 'neu'.

John Lawrence
quelle
6

Sie können in den Bearbeitungsmodus wechseln, indem Sie M- ^ drücken (Option-Shift-6 auf einem Mac).

Geben Sie Folgendes ein:

! 123M- ^

Und Sie bearbeiten den Befehl Nr. 123. Es ist so, als würde man Strg-R verwenden, aber mit der Ausrufezeichen-Syntax beginnen.

James Moore
quelle
Kann M-^man sich wieder an etwas Fingerfreundlicheres binden?
Blaz
4

Anstatt den historyBefehl zu verwenden, binden Sie history-search-backward/ history-search-forwardan Tastenkombinationen, an die Sie sich leicht erinnern können (ich bevorzuge PgUp / PgDown). Fügen Sie dazu Folgendes in Ihre .inputrcDatei ein:

"<key code>":  history-search-backward
"<key code>":  history-search-forward

Um <key code>, geben Sie Ctrl-V <key>in der Schale, und ersetzen Sie den Start ^[mit \ein welcher ausgegeben wurde.

Nachdem dies eingerichtet ist, können Sie einfach somePgUp eingeben und drücken, um zu erhalten some_long_command. Wenn Sie some_long_command with_some_argeinen ähnlichen Befehl some_long_command with_some_other_argspäter im Verlauf benötigen , können Sie ihn durchlaufen, bis Sie ihn erreichen, indem Sie somePgUp eingeben und dann wiederholt drücken, oder Sie können somePgUp eingeben, den Cursor an die Stelle bewegen, an der sich die beiden Befehle zu unterscheiden beginnen. Geben Sie ein paar Zeichen ein und drücken Sie erneut PgUp. Diese Fähigkeit, schnell durch ähnliche Befehle zu blättern / zu unterscheiden, macht es meiner Meinung nach zu einem viel komfortableren Werkzeug als Ctrl-R.

Tgr
quelle
3

Sie können auch setzen

shopt -s histverify

Dies führt dazu .bash_profile, dass eine Verlaufserweiterung in Ihrer Befehlszeile angezeigt wird, ohne sie auszuführen, sodass Sie sie vorher bearbeiten können.

chepner
quelle
1

Sie können versuchen, "Box vorschlagen" -ähnlichen Verlauf https://github.com/dvorka/hstr zu versuchen - es liest den Bash-Verlauf und ermöglicht eine schnelle Navigation.

hh

Um den letzten Befehl zu erhalten, geben Sie einfach hh ein, navigieren Sie zum Befehl und verwenden Sie den Rechtspfeil, um ihn in die Befehlszeile zu bringen (wo Sie ihn bearbeiten und / oder einen Kommentar hinzufügen können).

Martin Dvorak
quelle
0

^ p, um den zuletzt eingegebenen Befehl in Unix / Solaris abzurufen

SudhakarM
quelle
0

Stellen

alias r = 'fc -s'

In Ihrem .bashrc(Home-Verzeichnis) können Sie dann einfach eingeben

r <whatever>

An der Eingabeaufforderung führen Sie eine Kopie des letzten <whatever>Befehls (dieselben Parameter) aus, der sich in Ihrem Verlauf befindet. Drücken Sie einfach den Pfeil nach oben, um zu sehen, was Sie ausgeführt haben, wenn Sie das Bedürfnis haben.

Futter
quelle