为什么 Bash 在快捷方式中重置,例如绑定中的 alt-0 不起作用
bind -x '"\e0":"reset"'
它仅在屏幕清除后的第一个顶部/时间起作用(给出可见的按键回声)
,然后继续作为不可见的回声按键
有什么正确的解决办法吗?
答案1
太长了;博士
bind -x '"\e0":reset; stty lnext "" discard "" -icrnl -icanon -echo'
分析
我在 Kubuntu 22.04 LTS 中进行了测试。
stty -a -F /dev/pts/X
这是交互式 Bash 读取时的示例输出/dev/pts/X
:
speed 38400 baud; rows 21; columns 188; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = <undef>; discard = <undef>; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl ixon -ixoff
-iuclc -ixany imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig -icanon iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -flusho -extproc
这是在触发击键后stty -a -F /dev/pts/X
交互式 Bash 读取的示例输出:/dev/pts/X
reset
speed 38400 baud; rows 21; columns 188; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -flusho -extproc
最重要的是icanon
,它应该在哪里-icanon
。这意味着在reset
按键触发后,终端就处于规范模式,即在您按下Enter(或Ctrl+ j、或Ctrl+ m;或Ctrl+ d)之前,它不会将字符传递给阅读程序(此处:Bash)。
在规范模式下,你可以按Alt+0然后你会看到^[0
(由于echo
设置),但 Bash 只会在 后读取它(并对其做出反应)Enter。 Bash还将Enter设置更改为它所期望的,因此稍后您的Alt+0将再次工作(并再次“中断”)。
Bash 期望的设置(并强加,但显然不是在reset
击键触发后直接设置)包括-icanon
。在此模式下,未被终端驱动程序拦截的每个击键都会立即传递到 Bash。
解决方案
您可以通过不仅使击键运行reset
,而且至少stty -icanon -echo
在之后运行来解决问题reset
。我上面发布的两个输出之间还有更多差异;完整的修复位于stty lnext "" discard "" -icrnl -icanon -echo
.所以绑定应该是:
bind -x '"\e0":reset; stty lnext "" discard "" -icrnl -icanon -echo'