Suchen Sie nach einem vorherigen Befehl mit dem gerade eingegebenen Präfix


67

Wir können den Aufwärts- und Abwärtspfeil verwenden, um im Befehlsverlauf zu navigieren.

Wenn wir in einigen IDEs, wie z. B. Matlab, etwas eingeben und dann die Pfeiltasten drücken, scrollen wir nur zwischen den Verlaufsbefehlen, beginnend mit der von uns eingegebenen. Das ist sehr praktisch, aber in einem Shell-Terminal funktioniert das nicht.

Gibt es eine Möglichkeit, eine ähnliche Funktion in einem Shell-Terminal zu erhalten? Und noch andere Tipps zur Verbesserung der Effizienz bei der Terminalnutzung?


Sie könnten einfach eine Shell verwenden, die eine solche Funktion bietet, wie fish;)
yoann

@yoann Sie nehmen an, dass Bash nicht. Über readline ist dies jedoch standardmäßig nicht möglich.
Muru

@muru Ich kenne STRG + R in der Bash, und die Antwort von egmont bietet eine gute Möglichkeit, dies mit Bild auf / Bild ab zu tun. Gibt es jedoch eine Möglichkeit, dies mit den Pfeiltasten zu tun?
Yoann

1
@yoann check out unix.stackexchange.com/a/76591/70524 . Statt \e[5~und die \e[6~Verwendung \e[A, \e[B.
Muru

Antworten:


95

Was Sie suchen, ist CtrlR.

Geben Sie einen CtrlRTeil des gewünschten Befehls ein und geben Sie ihn dann ein. Bash zeigt den ersten passenden Befehl an. Tippe weiter CtrlRund Bash durchläuft alle vorherigen Übereinstimmungsbefehle.

Um im Verlauf rückwärts zu suchen, geben Sie CtrlSstattdessen Folgendes ein. (Wenn CtrlSdies bei Ihnen nicht der Fall ist, bedeutet dies wahrscheinlich, dass Sie die XON / XOFF-Flusssteuerung deaktivieren müssen. Führen Sie dazu Folgendes aus stty -ixon.)

Dies ist unter "Suchen" in dokumentiert man bash.


1
Ctrl-Qum den eingefrorenen Zustand zu verlassen, wenn Sie bereits getroffen haben, Ctrl-Sohne zuvor die Flusskontrolle auszuschalten, und Ihr Terminal eingefroren hat.
HongboZhu

26

Legen Sie diese in Ihre ~/.inputrc:

"\e[5~": history-search-backward
"\e[6~": history-search-forward

Diese machen Page Upund Page Downverhalten sich so, wie Sie es wünschen. (Einige Distributionen haben es bereits für Sie konfiguriert.) Ich persönlich finde diesen Weg praktischer als Ctrl+ Roder history.


Dies ist der bequemste Weg in allen aktuellen Antworten. Könnten Sie uns eine kleine Erklärung zum Funktionsmechanismus geben?
Lee

3
~/.inputrcoder /etc/inputrcoder die Datei, auf die die Umgebungsvariable verweist, $INPUTRCist die Konfigurationsdatei für die Zeilenbearbeitung aller Anwendungen, die readline verwenden, einschließlich bash (Ihre Shell). Es verfügt über bestimmte eingebaute Funktionen zur Zeilenbearbeitung, darunter die beiden folgenden: Suchen Sie in der Handbuchseite von bash nach einem dieser Schlüsselwörter, um weitere Informationen zu erhalten. \e[5~/ \e[6~sind die Escape-Sequenzen, die von den Page Up / Down-Tasten in den meisten Terminal-Emulatoren generiert werden; Starten Sie dazu den catBefehl und drücken Sie diese Tasten (das Escape-Byte wird im Terminal als ^[, in inputrc als dargestellt \e).
Egmont

Das Beispiel in Ihrer ursprünglichen Frage besagt, dass die Auf- / Ab-Tasten in Matlab auf diese Weise funktionieren. Es wäre interessant zu sehen, was passiert ist, wenn Sie die Abfolge von Auf und Ab in inputrc platzieren und dieser Aktion zuweisen. würde es richtig funktionieren oder böse Nebenwirkungen haben, da es mit ihrem Standardverhalten in Konflikt steht. Ich weiß nicht, ich würde mich freuen, Ihre Erkenntnisse zu hören, wenn Sie damit experimentieren.
Egmont

Wenn ich es tue echo $INPUTRC, ist es leer. Ich benutze Ubuntu 14.04
JorgeeFG

2
Ich persönlich bevorzuge es, den Auf- und "\e[A": history-search-backward"\e[B": history-search-forward
Abwärtspfeil zu

9

Neben ^ r / ^ s Geschichte suche ich:

alt.Fügt das letzte "Wort" des vorherigen Befehls am Cursor ein. Wiederholen Sie diesen Vorgang, um das letzte Wort älterer Befehle abzurufen. (Beachten Sie jedoch, dass ein abschließendes &Wort als letztes Wort für Hintergrundbefehle gilt.)

Das ist super praktisch für mkdir foo, cdAlt-Punkt. Noch schneller als Pfeil nach oben, ^ a, alt-d (löscht vorwärts Wort) cd.

Um das vorletzte Wort zu erhalten, verwenden Sie esc - 2 alt+.(dh verwenden Sie ein numerisches Argument im Emacs-Stil für alt+.. Negative Zählungen am Ende, positive Zählungen am Anfang). Irgendwann ist es schneller, nach der Maus zu greifen und sie zu kopieren / einfügen, oder nach oben zu gehen und einen Teil davon zu markieren (siehe unten).


Wenn Ihr Terminal ordentlich eingerichtet ist, werden Strg-Links und Strg-Rechts wortweise vor- und zurückgespult. Wenn nicht, tun hoffentlich mindestens Alt-B und Alt-F dasselbe.


Strg- / ist ein Rückgängigmachen. Sie können die automatische Wiederholung zum Löschen von Wörtern viel effizienter verwenden, wenn Sie sie rückgängig machen können, wenn Sie ein wenig überschießen.


Stärkeres Mischen / Anpassen von Befehlen ergibt sich aus der Verwendung des Kill-Rings, der genau wie in Emacs funktioniert. ctrl-y, um die letzte Strg-w / Strg-u / Strg-Rücktaste / Alt-d einzufügen. alt-y, um durch älteren getöteten Text zu blättern.

Mehrere Strg-w oder was auch immer in einer Reihe machen bei Kill-Ring-Eintrag. Verwenden Sie den Pfeil nach links und rechts oder etwas, um den Eintrag aufzubrechen, wenn Sie zwei Dinge entfernen und später nur eine einfügen möchten.

Wenn Sie all dies kombinieren, können Sie

  • Starten Sie die Eingabe eines Befehls
  • ctrl-r, um zu einem alten Befehl zurückzukehren und einen Teil davon mit control-w oder ähnlichem abzurufen.
  • esc-r oder alt+rzum Wiederherstellen, wie es war, bevor Sie einen Teil davon gelöscht haben.
  • alt- >um zum Ende der Geschichte zu gelangen (dh den ganzen Weg nach unten), um zu dem Befehl zurückzukehren, mit dem Sie sich gerade befanden.

Weitere interaktive Anwendungstipps:

Aktivieren shopt -s globstar, damit Sie dies tun können **/*.c(rekursiv einschließlich des aktuellen Verzeichnisses). Manchmal praktisch für den interaktiven Gebrauch, ist aber normalerweise find -name '*.c' -exec foo {} +besser.

Wenn Sie Bash-Skripte schreiben, ist es praktisch, diese auch shopt -s extglobin Ihren interaktiven Shells zu aktivieren. Sie werden manchmal eine Verwendung für *.!(c|h)Dinge finden , die mit Dateien übereinstimmen, die nicht mit .c oder .h enden.

Finden Aliase Sie mögen ls -l, lessund etwas anderes tun Sie viel. ( cp -i, mv -i, Und rm -Isind schön. Lassen Sie sich nicht in die Gewohnheit , je auf sie ein selektives rm zu tun. GNU rm der -I fragt einmal für alle args.)

Ich mag alias m=less(m für "mehr"). Ich habe mich lessmit der vorherigen / nächsten Datei ( ) eingerichtet ,und an diese .gebunden lesskey. Die Standardeinstellung ist eine Multitastendrucksequenz, die nicht mit automatischer Wiederholung verwendet werden kann.


Ich mache gerne alles im GNU-Bildschirm. Ich finde es einfacher, nummerierte Bildschirmfenster im Auge zu behalten, als eine Schiffsladung von Registerkarten in Konsole (oder einem anderen Terminalemulator, den ich ausprobiert habe). Wenn Sie es noch nicht wissen screen, lernen Sie tmux, weil es neuer und weniger krumm ist.

Um so etwas wie die Funktionalität des Öffnens einer neuen Shell mit der gleichen CWD wie einer anderen Shell zu erhalten, verwende ich einen benutzerdefinierten Hook für cd / pushd / popd, mit dem ich cds 8eine CD in das Verzeichnis erstellen kann, in dem sich meine Shell in Bildschirmfenster 8 befindet. Dies funktioniert auch für Shells außerhalb der Bildschirmsitzung, sofern nur eine Bildschirmsitzung vorhanden ist.


Meins scheint nicht "richtig konfiguriert" zu sein. Viele der Verknüpfungen, die ich hier sehe, funktionieren nicht, ich verwende das Standard-Terminal von Ubuntu 14.04. Wie kann ich es konfigurieren?
JorgeeFG

@JorgeeFG: Ich denke, es hat bei mir mit gnome-terminalUbuntu 14.04 sofort funktioniert , bevor ich zu KDE gewechselt bin. Die relevante Option befindet sich in Ihren Terminaleinstellungen, esc-Präfix vs High-Bit, und möglicherweise in einigen anderen Einstellungen. Einige von ihnen arbeiten nicht perfekt für mich durch SSH. (zB Strg links / rechts munge den Escape-Code für die Pfeiltaste, und ich werde 5Dbuchstäblich erscheinen)
Peter Cordes

7

Fügen Sie die folgenden Zeilen zu Ihren hinzu ~/.inputrc

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

Dies ähnelt der Antwort von egmont, verwendet jedoch anstelle von Bild auf und Bild ab die Escape-Sequenzen für Pfeil auf und Pfeil ab. Auf diese Weise ist die Verwendung auf einem Mac wesentlich bequemer.


4

Ich neige immer dazu, meine Computer mit einem großen HISTSIZE- Wert zu konfigurieren, damit eine längere Verlaufsliste sowie HISTTIMEFORMAT mit dem Zeitstempelwert gespeichert werden, damit ich sehen kann, wann der Befehl ausgeführt wurde.

export HISTSIZE=10000
export HISTTIMEFORMAT="%m/%d/%Y %T "

3

Das Mittel, das ich normalerweise benutze, ist, den historyBefehl mit zu kombinierengrep

IE:

history | grep <command im looking for>

Daraufhin wird ein nummerierter Verlauf der von Ihnen eingegebenen Befehle angezeigt, die diesen Befehl enthalten. Anschließend können Sie Folgendes verwenden:

!<number listed in history command>

um diesen Befehl zu wiederholen.

IE:

history | grep history

142  history
143  history | grep lvresize
568  history | grep echo
570  history | grep echo
571  history | grep history

gefolgt von: !571

werde wiederholen history | grep history


1
CR = viel besser + viel sicherer
PSkocik

1
Vielleicht finde ich persönlich einen Verlauf, der an grep weitergeleitet wird, um die meisten Befehle schneller zu finden. Was Safer betrifft, bin ich mir nicht sicher, was Sie damit meinen. Welche Risiken birgt die Verwendung von Historie, wenn man sie mit cR durchsucht?
Soße

2
@Gravy Ich vermute, PSkocik bedeutet, dass die !Auswechslung in der Vergangenheit weniger sicher ist.
Derobert

3
@Gravy Die inhärenten Risiken würden versehentlich die falsche Linie bekommen. Keine Ahnung, warum Ihr Terminal eingefroren ist, es sei denn, Sie haben Control-S verwendet und die Flusskontrolle xon / xoff aktiviert (häufig die Standardeinstellung). Wenn ja, bringt Control-Q es zurück.
Derobert

1
Ich stimme @PSkocik zu, cr ist viel besser, weil es einfacher ist, die Verlaufszeile zu bearbeiten, als sie einfach auf die gleiche Weise erneut auszuführen. Das erneute Ausführen des exakt gleichen Befehls ist ein trivialer Fall, in dem Sie Zeit sparen können, wenn Sie Änderungen an komplexen Einzeilern erneut eingeben oder eine andere Datei in einem langen Pfad durch Tabulatoren vervollständigen. Siehe meine Antwort.
Peter Cordes

1

Ich habe täglich 4 Tipps (und einige andere) in meinem Bash-Terminal verwendet:

  • Letzten Befehl ausführen: !!

  • Führen Sie den Befehl N aus dem Protokoll aus: !N

  • Letzten Befehl beginnend mit dem Präfix aus dem Verlauf ausgeben: !prefix:p

  • Führen Sie den letzten Befehl aus, beginnend mit dem Präfix aus dem Verlauf: !prefix


1

Wenn es in Ordnung ist , oh-my-zshzsh anstelle von Ihnen zu verwenden, verwenden bashSie oh-my-zsh dafür.

Es enthält den Pfeil nach oben und unten, der Sie durch den Befehlsverlauf führt. Es ermöglicht auch die gleiche Navigation, wenn Sie bereits Text eingegeben haben (als Mathlab).

Bearbeiten: Es enthält auch andere entwicklerorientierte Inhalte, wie z. B. Aliase und Themen. Diese Extras machen die Distribution größer und komplexer zu bedienen.

https://github.com/robbyrussell/oh-my-zsh


1
oh-my-zshenthält Tonnen von Sachen. Sie können genauso gut sagen: Diese Funktion ist in der Distribution enthalten, wenn Sie nur eine bestimmte Einstellung oder App benötigen.
Muru

Ich habe den Beitrag bearbeitet: Ich habe gewarnt, dass er größer als eine einfache App ist.
user9869932

1

Fügen Sie ~ / .bashrc den folgenden Alias ​​hinzu

alias h='history | awk '"'"'{$1="";print}'"'"' |sed "s/^ *//" |grep -v "^h " | sort | uniq | grep'

Verwendung: h fireLiefert mir eine Liste mit Befehlen, die Feuer enthalten . oder h ^fireerhalten Sie mir eine Liste der Befehle beginnen mit Feuer .

Dies ist nützlich, wenn ich eine Reihe von Befehlen gleichzeitig anzeigen möchte.

Übrigens '"'"'ist hässlich, aber ich konnte keine anderen Möglichkeiten finden, einfache Anführungszeichen in einfachen Anführungszeichen zu vermeiden.


zu Ihrer Information - h="history | awk '{\$1=\"\"; print}'sollte funktionieren. Alternativ können Sie eine Funktion erstellen und diese aufrufen.
DarkHeart

Vielen Dank, DarkHeart, aber ich habe Ihren Code ausprobiert und festgestellt, dass er in meiner Umgebung nicht funktioniert. Vielleicht ist etwas in meiner anders
Hosi Golden
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.