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

相关内容