
(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 uptime
Befehl 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 readline
Dokumentation gelesen habe, sehe ich keine Möglichkeit, mit einer Tastenbelegung einen externen Befehl auszuführen.
Das Nächstliegende, was mir eingefallen ist, ist, meiner .inputrc
Datei 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 uptime
anschließ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, uptime
anstatt 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 -c
in 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 bash
Zeilenbearbeitungen werden von gesteuert ~/.inputrc
; vieles davon wird über das bind
eingebaute 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%M
fü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_number
usw. Im Grunde wie programmierbare Abkürzungen! und alle sind \C-g
nur 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 \n
am Ende Ihrer Sequenz muss es die Bindung für sein accept-line
. Beispiel:
"\C-m": accept-line
"\C-gu": "uptime\C-m"
Da es uptime
in die Befehlszeile eingegeben wird, befindet es sich in Ihrem Verlauf, was je nach Anwendungsfall entweder ein Vorteil oder ein Nachteil ist.
Hier ^M
ist 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