有没有办法轻松使SIGINT事件保持沉默,而不会让它们消失?

时间:2016-02-03 20:31:31

标签: ruby bash

我经常在我的ruby代码中使用这样的方法:

def register_sigint
  Signal.trap('SIGINT') { exit }
end

当我点击ctr + c时,程序通常会立即退出。

现在就是这样:

在我的主shell中,bash显示“^ C”

在新的一行。

有没有办法可以让它完全不显示?

我之所以想要这个:

我用红宝石问我考试题,然后填写答案+给他们着色。

现在,当我按ctrl + c退出时,我得到这两个字符,并且对齐变得混乱。这可能看起来很小,可能是,但它只会让我烦恼,因为我不需要阅读这两个我不需要的字符。

如果有任何帮助,我会很高兴。

以下是显示问题的图片:

http://i.imgur.com/OQV2xVe.png

橘红色的东西是Dir.pwd(当前工作目录)

^ C出现在之前。

2 个答案:

答案 0 :(得分:0)

在Ruby捕获信号之前显示^C,如果不使用使用C代码的库,则不能让它从Ruby中消失。但你可以做到

def register_sigint
  Signal.trap('SIGINT'){puts; exit}
end

在退出之前将^C放在单独的行上。

否则,您需要使用curses库或其变体来捕获密钥。

答案 1 :(得分:0)

Ruby没有生成^C;你的外壳是。假设你的shell有stty命令(除非你在Windows上,这很可能),你可以使用stty -ctlecho来禁用它。

为了说明这里,这是一个简单的程序,它打印点直到它收到SIGINT,然后它打印"再见!"并退出:

def setup!
  Signal.trap("INT") {
    shut_down!
    exit
  }
end

def shut_down!
  puts "Bye!"
end

setup!

loop do
  sleep 0.2
  print '.'
end

如果我们运行一段时间然后按Ctrl + C:

,这就是我们得到的
$ ruby dots.rb
.......^CBye!

不理想。

现在让我们修改setup!shut_down!方法来调用stty -ctlechostty ctlecho来分别禁用和重新启用控制字符的打印:

def setup!
  system "stty -ctlecho"

  Signal.trap("INT") {
    shut_down!
    exit
  }
end

def shut_down!
  system "stty ctlecho"
  puts "Bye!"
end

然后:

$ ruby dots.rb
.......Bye!

如果你想要stty来修改shell的行为似乎很奇怪,我当然明白,但事实上即使是核心的Ruby模块都做同样的事情,for example RubyGems

P.S。您可以做的另一件事是使用ANSI转义序列在您收到SIGINT时将游标备份两个字符,这将导致后续输出基本上"覆盖" ^C。向左移动光标的转义序列为\033[nD,其中n是字符数(reference here),因此:

def shut_down!
  print "\033[2D"
  puts "Bye!"
end