bash: 바인딩된 명령(예: redraw-current-line)을 프로그래밍 방식으로 호출할 수 있는 방법이 있나요?

bash: 바인딩된 명령(예: redraw-current-line)을 프로그래밍 방식으로 호출할 수 있는 방법이 있나요?

redraw-current-line키 입력에 대한 매핑을 사용하는 방법에 대한 많은 설명을 접했지만 bind사용자가 키 입력을 입력하지 않고도 다른 이유로(예: 타이머, 백그라운드 작업) 프롬프트를 다시 그리고 싶습니다. 쉬울 줄 알았는데 아무것도 못 찾겠어요. 감사해요!

답변1

나는 같은 문제에 직면했지만 만족스러운 것을 찾지 못했으므로 여기에 몇 가지 해결 방법이 있습니다.

${PS1@P}

최신 bash 버전에서는 자체 인쇄 프롬프트를 사용할 수 있습니다 echo "${PS1@P}". 변수 확장의 형태는 ${var@P}변수 내부의 프롬프트 이스케이프 문자를 확장하는 것을 의미합니다.

kill -WINCH "$$"

시도할 수 있는 또 다른 방법은 kill your 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평소와 같이 사용하지 않는 키를 바인딩한 다음 TIOCSTIioctl을 사용하여 해당 키를 시뮬레이션하는 것입니다(추가 권한 없이도 계속 작동함).현재의리눅스에서는 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에서만 작동합니다. TIOCSTIioctl 번호는 이를 지원하는 다른 시스템에서 다를 수 있습니다.


노트: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

관련 정보