bash readline: 外部コマンドに対するキーバインディングの実行

bash readline: 外部コマンドに対するキーバインディングの実行

(背景:私は長い間tcshを使用してきましたが、徐々にbashに切り替えて、便利なtcsh関連と同等の機能を見つけようとしています。)

tcshでは、外部コマンドを実行するキーバインディングを定義できます。たとえば、次のようになります。

bindkey -c ^Gu uptime

tcsh に「Control-G u」と入力するとuptimeコマンドが実行されます。 Enterを入力する必要はなく、コマンドが私の履歴に表示されず、入力行の途中で実行できます(一部のコマンドでは、後者が特に役に立つと思います)。

bash には GNU readline ライブラリを介した同様のキーバインディングメカニズムがあり、$HOME/.inputrcバインディングは(または他の場所で)指定されます。ただし、文書を読んだ後は、info readlineキーバインディングを使用して外部コマンドを実行する方法を見つけることができません。

私が考えることができる最も近いのは、私の.inputrcファイルに次のようなものを追加することです。

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

しかし、これはコマンドを実行せずに、私が何かを入力してuptimeEnterを押したかのように動作します。コマンドは私の履歴に表示され(大丈夫です)、空白行でのみ機能します。コマンドを入力すると、コマンドを実行するのではなく"echo control-Gu"印刷されます。uptime

もう一つのマイナーな欠点は、バインディングがPerlデバッガなど、GNU readlineを使用する他のコマンドに影響を与えることです。

bindkey -cキーシーケンスを指定された外部コマンドの実行にマッピングしてbashでtcshの効果をシミュレートする方法はありますか?

重要な場合は、Ubuntu 12.04ベータ2でbash 4.2.24を使用しています。

答え1

すべての行の編集がbash;で制御されるわけではありません。~/.inputrcこれらのほとんどはbind組み込みによって構成されています。この場合は、次のようなものが欲しい

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

あなたの~/.bashrc

答え2

別の答えは、新しい行でコマンドを実行するソリューションを提供します。これはいくつかのケースでは便利ですが、ほとんどの場合、私のワークフローは次のようになります。

  • コマンドをインラインで実行した結果を自分のファイルに挿入します。現在のコマンドライン(以下の例)
  • 実際、バックグラウンドでコマンドを実行し、出力がなく、現在のコマンドラインは変更されません。

私は@geekosaurが示した変形よりもこれら2つの原則を頻繁に使用します。例は次のとおりです。

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

このバインディングCTRL-gd既存のコマンドを終了し(カットバッファに保存)、挿入しsome shell command(この場合はdate +%Y%m%d%H%M良いタイムスタンプを得るために)、そのコマンドを実行してから、保存したコマンドをコマンドラインの先頭に再度貼り付けます。

私のシステムからいくつかの情報を出力するコマンドがたくさんあり、他のコマンドラインでよく使用されますget_lan_ip, get_gw_ip, get_gw_pubip, get_ns_ip, get_root_block_dev, get_email_addr, get_phone_number。基本的にプログラム可能な略語と同じです!これ\C-gはすべて1回のクリックで完了します。

私にとって非常に便利な別のユースケースは、関数をインラインで呼び出すことです。欲しくない出力を生成しますが、mediaplayer_next, mediaplayer_pause, speakerphone_answer, ...端末を離れずに現在のウィンドウの内容を一時的に無視せずに何かをトリガーしたい場合など、バックグラウンドジョブを自動的にトリガーします。

答え3

許可された回答に追加するために実際に使用する必要はありませんbind -x。引き続き回答に追加できますが、シーケンスがinputrc終了したら\nバインディングでなければなりませんaccept-line。たとえば、

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

コマンドラインを入力すると、uptimeレコードに書き込まれます。これはユースケースに応じて長所と短所になる可能性があります。

MacとWindowsではキャリッジリターンですが、^M順序は重要ではありません。たとえば、次の事項も適用されます。

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

答え4

許可された回答で実行できるトリックをいくつか追加するには、次のものを使用することもできます。

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

現在のウィンドウを一番下に送ったり、xtermが開発した別のエスケープコードを送信したり、ウィンドウを中央に配置したり、ウィンドウを特定のピクセル位置に配置したりします。

また、参照してくださいvttest(1)(遊びながら素晴らしいエスケープシーケンスをたくさん学ぶことができることがわかりましたvttest)。https://invisible-island.net/xterm/ctlseqs/ctlseqs.html

関連情報