我遇到过许多关于如何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
像往常一样绑定一些未使用的密钥,然后使用TIOCSTI
ioctl 模拟该密钥(它仍然可以在没有额外权限的情况下工作)当前的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