在讨论了如何在会话之间保留命令行历史记录之后,我定义了以下别名:
alias node='env NODE_NO_READLINE=1 rlwrap node'
它非常适合历史持久性,但现在,每次我用Ctrl-C发送节点的".break"命令时,rlwrap也会接受它,但作为一个SIGINT:它会清除所有内容和自杀(如其手册页中所述),从而迫使我重新启动节点会话(必须调用我的var、funcs、requires等),而我只想".breach"…
有什么方法可以恢复经典的节点行为吗?
- Ctrl-C:中断
- 再次按Ctrl-C(或在空行上):退出
避免SIGINT
node
通过取消设置其中断字符VINTR
(通常为CTRL-C)来改变CTRL-C的含义,以避免它本来会得到的中断信号。
启动后,rlwrap
一直处于睡眠状态,直到您的终端或node
使用的伪终端(pty
)上发生了一些事情。这个"某物"可以是您的按键,也可以是node
的输出。
每次发生这种情况时,rlwrap
都会将nodes
的终端设置(包括VINTR
))复制到自己的tty中。
然而,如果node
仅更改其终端设置,则这本身不会唤醒rlwrap
,从而将旧设置保留在自己的tty上。透明度将被破坏:当您按下CTRL-C时,rlwrap
仍将其解释为SIGINT
,而node
将理解.break
命令。
有一种特殊的、非常模糊的pty
模式(EXTPROC),它允许pty主机(rlwrap
)被从机在终端设置中的更改唤醒,但这是非常不可移植的。这就是为什么,自0.41版本以来,rlwrap
有一个不那么优雅的--polling
选项,它每40毫秒唤醒一次,并复制从属设备的终端设置。
转发CTRL-C
从0.43版本开始,rlwrap
即使在读线模式下也可以通过绑定直接转发特殊密钥CCD_ 22中的CCD_ 21的这样一个密钥:
$if node
"C-c": rlwrap-direct-keypress
$endif
然而,当node
本身使用readline(尝试NODE_NO_READLINE=1 node
,然后键入CTRL-C)时,仅给予CTRL+C特殊处理
在这种情况下(即,当命令进行自己的行编辑时),必须强制rlwrap
进入读行模式:
$ rlwrap --always-readline node
这有一个不幸而不可避免的缺点,那就是从来没有命令要求单一按键(Continue? Y/N
)必须键入extra输入。
然后仍然是上面概述的问题:如果终端的中断字符没有改变,node
将永远看不到CTRL-C(而是得到SIGINT
)
有两种解决方案。任一:
stty intr undef # disable interrupt character
rlwrap --always-readline node
stty intr '^c' # re-enable CTRL-C
或:
rlwrap --polling --always-readline node # --polling means: continually wake up and wacth node's interrupt character
包装
长话短说:
- 将
"C-c": rlwrap-direct-keypress
添加到您的inputc
- 暂时取消设置终端的中断字符,或如上所述使用
rlwrap --polling --always-readline
- 试着使用额外的Enter来实现单按键