我正在使用PTY库在ruby中编写终端模拟器。 /dev/tty0
是连接到键盘的设备文件。我产卵壳这样的:为什么ruby的PTY库在shell有子进程时无法捕获输入?
shell = PTY.spawn 'env TERM=ansi COLUMNS=63 LINES=21 sh -i < /dev/tty0'
它主要的工作,但是当一个子进程在shell启动,shell[0]
不输出输入到该子键盘。例如:当我通过shell[1]
发送"cat\nasdf"
时,"cat"
通过shell[0]
返回,但"asdf"
不通过。为什么会发生这种情况,我该如何解决?
编辑:
这是我的代码。 ChumbyScreen
是一个外部模块,用于控制我为此编写的嵌入式设备(称为“Chumby”)的屏幕。 write
方法在屏幕上放置一个字符。
require 'pty'
def handle_escape(io)
actions = 'ABCDEFGHJKSTfmnsulh'
str, action = '', nil
loop do
c = io.read(1)
if actions.include? c
action = c
break
else
str += c
end
end
case action
when 'J'
ChumbyScreen.x = 0
end
end
system '[ -e /dev/tty0 ] || mknod /dev/tty0 c 4 0'
shell = PTY.spawn 'env TERM=ansi COLUMNS=63 LINES=21 sh -i < /dev/tty0'
loop do
c = shell[0].read(1)
if c == "\e"
c2 = shell[0].read(1)
if c2 == '['
handle_escape shell[0]
next
else
c += c2
end
end
ChumbyScreen.write c
end
阅读shodanex的回答后,我尝试这样做:
require 'pty'
def handle_escape(io)
actions = 'ABCDEFGHJKSTfmnsulh'
str, action = '', nil
loop do
c = io.read(1)
if actions.include? c
action = c
break
else
str += c
end
end
case action
when 'J'
ChumbyScreen.x = 0
end
end
system '[ -e /dev/tty0 ] || mknod /dev/tty0 c 4 0'
shell = PTY.spawn 'env TERM=ansi COLUMNS=63 LINES=21 sh -i'
Thread.new do
k = open '/dev/tty0', File::RDONLY
loop do
shell[1].write k.read(1)
end
end.priority = 1
loop do
c = shell[0].read(1)
if c == "\e"
c2 = shell[0].read(1)
if c2 == '['
handle_escape shell[0]
next
else
c += c2
end
end
ChumbyScreen.write c
end
它的工作原理,但我已经输入的字符显示不出来,直到我按enter键。它必须以某种方式进行线路缓冲 - 我如何克服这一点?另外Control-C和Control-D什么都不做。我需要他们发送一个eof并终止一个进程。
你可以发表你的整个Ruby代码? – shodanex 2010-09-29 08:43:00
@shodanex:编辑。您的建议迄今为止有帮助,谢谢! – Adrian 2010-09-30 03:34:13
默认情况下,tty处于行读取模式。您可以尝试在原始模式下使用它,并在您的代码中处理Ctrl-C和Ctrl-D。 – shodanex 2010-09-30 09:59:09