bash: Есть ли способ вызывать команды привязки (например, redraw-current-line) программно?

bash: Есть ли способ вызывать команды привязки (например, redraw-current-line) программно?

Я наткнулся на ряд объяснений того, как сопоставить 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обычному режиму, а затем смоделировать этот ключ с помощью TIOCSTIioctl (это все равно будет работать без дополнительных привилегий натекущий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 h2phbø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

Связанный контент