我遇到过许多关于如何redraw-current-line
使用映射到击键的解释bind
,但我想出于其他原因(例如计时器、后台作业)重新绘制提示,而无需用户输入击键。我以为这很容易,但我找不到任何东西。谢谢!
小智 6
我遇到了同样的问题,但没有找到令人满意的东西,所以这里有一些解决方法。
\n\n${PS1@P}
在较新的 bash 版本中,您可以使用 自行打印提示echo "${PS1@P}"
。变量扩展的形式${var@P}
是指在变量内部扩展提示转义符。
kill -WINCH "$$"
您可以尝试的另一个技巧是使用 杀死您的 shell SIGWINCH
。这将导致 readline 重新绘制提示。例子:
$ (sleep 2; echo foo; sleep 2; kill -WINCH "$$") &\n[1] 2295\n<immediately press l and s; the "foo" text will mess up the current line>\n$ lsfoo\n<after 1s the prompt is redrawn again without the parasitic text>\n$ ls\n
Run Code Online (Sandbox Code Playgroud)\n\nioctl(TIOCSTI)
另一个技巧是redraw-current-line
像往常一样绑定一些未使用的密钥,然后使用 ioctl 模拟该密钥(它仍然可以在 Linux 中的当前TIOCSTI
tty上运行,无需额外的特权)。但你需要 C、perl、python 等:
$ bind \'"\\xff": redraw-current-line\'\n$ redraw_current_line(){ perl -e \'ioctl STDIN, 0x5412, $x = "\\xff"\' </dev/tty; }\n$ (sleep 2; echo foo; sleep 2; redraw_current_line) &\n.... same as in SIGWINCH example ...\n
Run Code Online (Sandbox Code Playgroud)\n\n最后一个技巧仅适用于 Linux;TIOCSTI
可能支持它的其他系统上的ioctl 编号是不同的。
注意:如果有人认为我应该require "sys/ioctl.h"
而不是硬连线 ioctl 数字:不,我不应该。即使在这种情况下偶然起作用,perl 的h2ph
也是 b\xc3\xb8rked,并且不应使用这些.ph
文件:
$ perl -e \'require "sys/ioctl.ph"; printf "%x\\n", TIOCGPTN()\'\n80005430\n$ cc -include stdio.h -include sys/ioctl.h -xc - \\\n <<<\'int main(){printf("%lx\\n",TIOCGPTN);}\' -o /tmp/foo && /tmp/foo\n80045430\n
Run Code Online (Sandbox Code Playgroud)\n\n注意真实事物上的额外位:80045430
!=80005430