9

在讨论了如何在会话之间保留命令行历史记录之后,我定义了以下别名:

alias node='env NODE_NO_READLINE=1 rlwrap node'

它非常适合历史持久性,但现在,每次我执行 Ctrl-C 来发送节点的“.break”命令时,rlwrap 也会接受它,但作为 SIGINT:它会清除所有内容并自杀(如其手册页中所述),因此强迫我重新启动节点会话(不得不回忆我的 var、funcs、requires 等),而我只是想“.break”......

有什么方法可以恢复经典节点行为?

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

1 回答 1

7

避免 SIGINT

nodeCTRL-C通过取消设置其中断字符VINTR(通常)来更改 的含义, CTRL-C以避免它本来会得到的中断信号。

启动后,一直处于休眠状态,直到您的终端或eg 使用rlwrap的伪终端 ( ) 发生某些事情。这个“东西”可以是你的按键,也可以是.ptynodenode

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

但是,如果node 更改其终端设置,则它本身不会唤醒rlwrap,从而将旧设置保留在自己的 tty 上。透明度将被打破:当您按下CTRL-C rlwrap时仍会将其解释为SIGINT,而node会理解.break命令。

有一个特殊的、非常隐蔽的 pty模式 ( EXTPROC ),它允许 pty master ( rlwrap) 通过从站对终端设置的更改来唤醒,但这是非常不便携的。这就是为什么,从 0.41 版开始,rlwrap有一个不太优雅的--polling选项,它使它每 40 毫秒唤醒一次并复制从站的终端设置。

向前CTRL-C

从 0.43 版开始,rlwrap即使在 readline 模式下,也可以通过将特殊键绑定到rlwrap-direct-keypressin来直接转发特殊键~/.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

这有一个不幸且不可避免的缺点,即无论何时命令要求单个按键 ( Continue? Y/N),都必须键入一个额外的Enter.

然后还有上面勾勒的问题:如果终端的中断字符没有改变,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 进行单次按键操作
于 2014-02-23T22:25:03.753 回答