Ruby:read_nonblock(???)打破“系统”命令

时间:2013-05-08 22:26:43

标签: ruby system stty

我有一个方法的两个版本,我遇到了同样的问题。

版本1

def read_char
  $stdin.raw!
  input = $stdin.getc.chr
  if input == "\e" then
     input << $stdin.read_nonblock(3) rescue nil
     input << $stdin.read_nonblock(2) rescue nil
  end
ensure
  $stdin.cooked!
  return input
 end

版本2

def read_char
  system("stty raw -echo") 
  input = $stdin.getc.chr
  if input == "\e" then
    input << $stdin.read_nonblock(3) rescue nil
    input << $stdin.read_nonblock(2) rescue nil
  end
ensure
  system("stty -raw echo")  
  return input
end

我对两者都有同样的问题。 具体来说,它们会修改Kernel#system命令的行为。

举个例子:

system("irb")
c=read_char
system("irb")

很容易看到系统的行为发生了变化,而在第二个版本中,inout并未从tty中提取。

请注意,当您按任意键时,这不会发生,只是一个被转换为转义序列的键,例如光标键。

那么如何修复?

PS

有人建议我在第二个地方运行系统(“strace -o logfile irb”)并检查读取语句。相反,我把两个铁丝网都拉了过来进行比较。对于除最后一个之外的所有读取语句都是相同的,并且它们都是如此。最后的阅读看起来不同:

1st system: read(0, "1\n", 1024)                    = 2
2nd system: read(0, 0x7ff805a53000, 1024)           = -1 EAGAIN (Resource temporarily unavailable)

0x7ff805a53000 is the address of a memory mapped region.

PPS

我在linux系统上这样做。

0 个答案:

没有答案