Я наткнулся на ряд объяснений того, как сопоставить 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)
Еще один трюк — привязать какой-нибудь неиспользуемый ключ к redraw-current-line
обычному режиму, а затем смоделировать этот ключ с помощью TIOCSTI
ioctl (это все равно будет работать без дополнительных привилегий натекущийtty в Linux). Но для этого вам понадобится 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; номер ioctl для TIOCSTI
других систем, которые его поддерживают, может быть другим.
Примечание:если кто-то думает, что мне следует require "sys/ioctl.h"
вместо жесткого подключения номера ioctl:Нет, не должен.. Даже если это сработает случайно вэтотслучае, perl's h2ph
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