bash readline: Tastenkombination, die einen externen Befehl ausführt

bash readline: Tastenkombination, die einen externen Befehl ausführt

(Hintergrund: Ich bin ein langjähriger Tcsh-Benutzer, steige allmählich auf Bash um und versuche, Äquivalente für einige nützliche Tcsh-spezifische Funktionen zu finden.)

In tcsh kann ich eine Tastenkombination definieren, die einen externen Befehl ausführt. Beispiel:

bindkey -c ^Gu uptime

Ich kann in tcsh „Strg-G u“ eingeben und der uptimeBefehl wird ausgeführt. Ich muss nicht die Eingabetaste drücken, der Befehl erscheint nicht in meinem Verlauf und ich kann ihn mitten in einer Eingabezeile ausführen (letzteres finde ich bei bestimmten Befehlen besonders nützlich).

Bash verfügt über einen ähnlichen Tastenbelegungsmechanismus über die GNU Readline-Bibliothek, wobei die Belegung in $HOME/.inputrc(oder anderswo) angegeben ist. Aber nachdem ich die info readlineDokumentation gelesen habe, sehe ich keine Möglichkeit, mit einer Tastenbelegung einen externen Befehl auszuführen.

Das Nächstliegende, was mir eingefallen ist, ist, meiner .inputrcDatei so etwas hinzuzufügen:

"\C-gu": "uptime\n"

aber das führt den Befehl nicht aus; es verhält sich vielmehr so, als hätte ich eingegeben und uptimeanschließend die Eingabetaste gedrückt. Der Befehl erscheint in meinem Verlauf (das ist ok) und funktioniert nur in einer leeren Zeile; wenn ich eingebe "echo control-Gu", wird gedruckt, uptimeanstatt den Befehl auszuführen.

Ein weiterer kleiner Nachteil besteht darin, dass die Bindung andere Befehle beeinflusst, die GNU Readline verwenden, wie etwa den Perl-Debugger.

Gibt es eine Möglichkeit, die Wirkung von Tcshs bindkey -cin Bash zu simulieren, indem der Ausführung eines angegebenen externen Befehls eine Tastenfolge zugeordnet wird?

Falls es wichtig ist, ich verwende Bash 4.2.24 unter Ubuntu 12.04 Beta 2.

Antwort1

Nicht alle bashZeilenbearbeitungen werden von gesteuert ~/.inputrc; vieles davon wird über das bindeingebaute konfiguriert. In diesem Fall möchten Sie etwas wie

bind -x '"\C-gu":uptime'

in deinem ~/.bashrc.

Antwort2

Die andere Antwort bietet eine Lösung, die den Befehl in einer neuen Zeile ausführt. Dies ist in einigen Fällen nützlich, aber meistens ist mein Workflow so, dass ich entweder

  • Fügen Sie das Ergebnis eines Inline-Execute-Befehls in meinaktuellBefehlszeile (Beispiel unten)
  • Führt den Befehl wirklich im Hintergrund aus, keine Ausgabe, keine Änderungen in der aktuellen Befehlszeile

Ich verwende diese beiden Prinzipien viel häufiger als die Variante, die @geekosaur gezeigt hat. Hier ist ein Beispiel:

bind '"\C-gd":"\C-u`date +%Y%m%d%H%M`\e\C-e\C-a\C-y\C-e"'

Diese Bindung CTRL- gdum den vorhandenen Befehl zu beenden (und ihn im Ausschneidepuffer zu speichern), fügt ein some shell command, in diesem Fall date +%Y%m%d%H%Mfür einen schönen Zeitstempel, führt das an Ort und Stelle aus und fügt den gespeicherten Befehl dann wieder an den Anfang der Befehlszeile ein.

Ich habe eine Reihe von Befehlen, die Informationen aus meinem System ausgeben, die ich regelmäßig in anderen Befehlszeilen verwende, denke ich get_lan_ip, get_gw_ip, get_gw_pubip, get_ns_ip, get_root_block_dev, get_email_addr, get_phone_numberusw. Im Grunde wie programmierbare Abkürzungen! und alle sind \C-gnur einen Tastendruck entfernt.

Der andere sehr nützliche Anwendungsfall für mich ist das Aufrufen von Funktionen inline, dasnichtAusgabe erzeugen, aber stillschweigend eine Hintergrundaktion auslösen, beispielsweise mediaplayer_next, mediaplayer_pause, speakerphone_answer, ...wenn ich Dinge auslösen möchte, ohne mein Terminal zu verlassen und ohne auch nur für einen Moment den aktuellen Windows-Inhalt aus den Augen zu verlieren ;)

Antwort3

Um der akzeptierten Antwort etwas hinzuzufügen, müssen Sie nicht unbedingt verwenden bind -x. Sie können es trotzdem zu Ihrem hinzufügen inputrc, aber statt \nam Ende Ihrer Sequenz muss es die Bindung für sein accept-line. Beispiel:

"\C-m": accept-line
"\C-gu": "uptime\C-m"

Da es uptimein die Befehlszeile eingegeben wird, befindet es sich in Ihrem Verlauf, was je nach Anwendungsfall entweder ein Vorteil oder ein Nachteil ist.

Hier ^Mist der Wagenrücklauf auf Mac und Windows, aber die Reihenfolge ist eigentlich egal. Zum Beispiel funktioniert auch Folgendes:

"\xxacceptline": accept-line
"\C-gu": "uptime\xxacceptline"

Antwort4

Um einige Tricks hinzuzufügen, die Sie mit der akzeptierten Antwort machen können, können Sie sogar etwas wie

bind -x '"\C-g": echo -en "\e[6t"'

um das aktuelle Fenster nach unten zu senden, oder andere von xterm erfundene Escape-Codes, um das Fenster zu zentrieren, das Fenster an einer bestimmten Pixelposition zu platzieren usw.

Siehe auch vttest(1)(es stellt sich heraus, dass man viele ausgefallene Escape-Sequenzen lernen kann, indem man einfach mit herumspielt vttest) undhttps://invisible-island.net/xterm/ctlseqs/ctlseqs.html

verwandte Informationen