我正在使用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