bash: プログラムでバインド コマンド (例: redraw-current-line) を呼び出す方法はありますか?

bash: プログラムでバインド コマンド (例: redraw-current-line) を呼び出す方法はありますか?

redraw-current-lineを使用してキーストロークにマップする方法についての説明はいくつかありますbindが、ユーザーがキーストロークを入力せずに、他の理由 (タイマー、バックグラウンド ジョブなど) でプロンプトを再描画したいと思います。これは簡単だと思っていましたが、何も見つかりません。ありがとうございます。

答え1

私も同じ問題を抱えていましたが、満足のいく解決策が見つからなかったため、いくつかの回避策を紹介します。

${PS1@P}

新しい bash バージョンでは、 を使用するとプロンプトを自分で印刷できますecho "${PS1@P}"${var@P}変数展開の形式は、変数内でプロンプト エスケープを展開することを意味します。

kill -WINCH "$$"

もう一つの方法は、 を使ってシェルを終了することですSIGWINCH。これにより、readline はプロンプトを再描画します。例:

$ (sleep 2; echo foo; sleep 2; kill -WINCH "$$") &
[1] 2295
<immediately press l and s; the "foo" text will mess up the current line>
$ lsfoo
<after 1s the prompt is redrawn again without the parasitic text>
$ ls

ioctl(TIOCSTI)

さらにもう1つのトリックは、未使用のキーを通常どおりにバインドしredraw-current-line、そのキーをTIOCSTIioctlでシミュレートすることです(追加の権限がなくても動作します)。現在Linux の tty など)。ただし、そのためには C、perl、python などが必要になります。

$ bind '"\xff": redraw-current-line'
$ redraw_current_line(){ perl -e 'ioctl STDIN, 0x5412, $x = "\xff"' </dev/tty; }
$ (sleep 2; echo foo; sleep 2; redraw_current_line) &
.... same as in SIGWINCH example ...

この最後のトリックは Linux 専用です。TIOCSTIこれをサポートする可能性のある他のシステムでの ioctl 番号は異なります。


注記:require "sys/ioctl.h"ioctl 番号をハードワイヤードする代わりに、次のようにすべきだと考える人がいるかもしれません。いいえ、そうすべきではありません偶然にうまくいったとしてもこれこの場合、perlはh2ph壊れており、.phファイルはない利用される:

$ perl -e 'require "sys/ioctl.ph"; printf "%x\n", TIOCGPTN()'
80005430
$ cc -include stdio.h -include sys/ioctl.h -xc - \
   <<<'int main(){printf("%lx\n",TIOCGPTN);}' -o /tmp/foo && /tmp/foo
80045430

実際の余分な部分に注目してください: 80045430!=80005430

関連情報