bash:有沒有辦法以程式方式呼叫綁定指令(例如redraw-current-line)?

bash:有沒有辦法以程式方式呼叫綁定指令(例如redraw-current-line)?

我遇到過許多關於如何redraw-current-line使用映射到擊鍵的解釋bind,但我想出於其他原因(例如計時器、後台作業)重新繪製提示,而無需用戶輸入擊鍵。我以為這很容易,但我找不到任何東西。謝謝!

答案1

我遇到了同樣的問題,但沒有找到令人滿意的東西,所以這裡有一些解決方法。

${PS1@P}

在較新的 bash 版本中,您可以使用 自行列印提示echo "${PS1@P}"。變數擴展的形式${var@P}是指在變數內部擴展提示轉義符。

kill -WINCH "$$"

您可以嘗試的另一個技巧是使用 殺死您的 shell 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)

另一個技巧是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 數字:不,我不應該。即使它偶然起作用在這種情況下,perlh2ph是 børked,而且.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

相關內容