我正在尝试编写一个Ruby脚本,在幕后以交互方式运行mount
命令 。问题是,如果我将mount命令的输入和输出重定向到管道,它就不起作用。不知何故,mount似乎意识到它并没有直接与stdin / stdout对话并且摔倒了。要么是这样,要么是影响所有交互命令的更广泛的问题;我不知道。
我希望能够逐行解析mount
的输出,并在询问问题时将答案推送到输入管道。这不应该是一种不合理的期望。有人可以帮忙吗?
示例:
def read_until(pipe, stop_at, timeoutsec = 10, verbose = false)
lines = []; line = ""
while result = IO.select([pipe], nil, nil, timeoutsec)
next if result.empty?
begin
c = pipe.read(1) rescue c = nil
end
break if c.nil?
line << c
break if line =~ stop_at
# Start a new line?
if line[-1] == ?\n
puts line if verbose
lines << line.strip
line = ""
end
end
return lines, line.match(stop_at)
end
cmd = "mount.ecryptfs -f /tmp/1 /tmp/2"
status = Open3::popen2e(cmd) { |i,o,t|
o.fcntl(3, 4) # Set non-blocking (this doesn't make any difference)
i.fcntl(3, 4) # Set non-blocking (this doesn't make any difference)
puts read_until(o, /some pattern/, 1, true) # Outputs [[], nil]
}
我也试过spawn
:
a, b = IO.pipe
c, d = IO.pipe
pid = spawn(cmd, :in=>a, :out=>d)
puts read_until(c, /some pattern/, 1, true) # Outputs [[], nil]
我已经尝试了subprocess
,pty
以及其他一系列解决方案 - 基本上,如果它在谷歌上,我已经尝试过了。似乎mount 知道如果我没有将它传递给真正的shell,并故意阻止。参见:
pid = spawn(cmd, :in=>STDIN, :out=>STDOUT) # Works
pid = spawn(cmd, :in=>somepipe, :out=>STDOUT) # Blocks after first line of output, for no reason whatsoever. It's not expecting any input at this point.
我甚至试图产生一个真正的shell(例如bash)并通过输入管道向它发送mount命令。同样的问题。
请忽略上面的任何明显错误:我今晚尝试了几种解决方案,因此实际代码已被多次重写。我在记忆中写了以上内容。
我想要的是以下内容:
等等。