使用带有Node.js REPL的rlwrap,如何通过rlwrap将节点'.break'(Ctrl-C)解释为SIGINT?

时间:2014-02-18 19:46:08

标签: node.js read-eval-print-loop sigint rlwrap

在讨论了如何preserve command line history between sessions之后,我定义了以下别名:

alias node='env NODE_NO_READLINE=1 rlwrap node'

它完美适用于历史持久性,但现在,每次我按Ctrl-C发送节点' .break'命令,rlwrap也接受它,但作为一个SIGINT:它清除一切和自杀(如its man page中所述),从而迫使我重新启动一个节点会话(必须回忆我的var,funcs,需要等),而我只是想' .break' ...

有什么方法可以取回经典节点行为?

  • Ctrl-C:中断
  • 再次
  • Ctrl-C(或空白行):退出

1 个答案:

答案 0 :(得分:5)

避免SIGINT

node通过取消设置interrupt character VINTR(通常是 CTRL-C )来改变 CTRL-C 的含义,以避免中断信号否则会得到。

启动后,rlwrap一直处于休眠状态,直到您的终端或伪终端(pty)上发生了某些情况,例如node。这个“东西”可以是你的按键,也可以是node的输出。

每次发生这种情况时,rlwrap都会将nodes的终端设置(包括VINTR))复制到自己的tty。

但是,如果仅node 更改其终端设置,则此功能本身不会唤醒rlwrap,因此会保留旧设置TTY。透明度将被破坏:按 CTRL-C rlwrap仍将其解释为SIGINT,而node则理解为.break }命令。

我有一个特殊的,非常模糊的pty模式(EXTPROC),它允许pty master(rlwrap)被终端设置中的slave更改唤醒,但是这个是非常不便携的。这就是为什么,因为版本0.41,rlwrap具有更不优雅的--polling选项,使其每40毫秒唤醒并复制从属的终端设置。

转发 CTRL-C

从版本0.43开始,rlwrap即使在读取模式下通过绑定也可以直接转发特殊键 rlwrap-direct-keypress~/.inputrc的关键词:

$if node
   "\C-c": rlwrap-direct-keypress
$endif

但是,node 给出 CTRL + C 特殊处理,当它本身使用readline时(尝试NODE_NO_READLINE=1 node然后键入 CTRL -C )看看我的意思)

在这种情况下(即当命令执行自己的行编辑时),必须强制rlwrap进入readline模式:

$ rlwrap --always-readline node

这有一个令人遗憾和不可避免的缺点,即每当一个命令要求单身时 keypresses(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
  • 尝试使用单个按键的额外输入