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평소와 같이 바인딩한 다음 ioctl로 해당 키를 시뮬레이트하는 것입니다 TIOCSTI.현재의리눅스에서는 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에만 해당됩니다. 이를 지원할 수 있는 다른 시스템 의 ioctl 번호 TIOCSTI는 다릅니다.


메모:누군가 내가 require "sys/ioctl.h"ioctl 번호를 직접 배선하는 대신에 해야 한다고 생각한다면:아니, 그러면 안 된다. 우연히 작동하더라도이것이 경우 Perl은 파일이 h2ph저장되어 있어야 하며 .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

관련 정보