如何从(Ruby)脚本交互式运行mount命令?

时间:2014-09-29 23:18:18

标签: ruby linux shell interactive mount

我正在尝试编写一个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]

我已经尝试了subprocesspty以及其他一系列解决方案 - 基本上,如果它在谷歌上,我已经尝试过了。似乎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命令。同样的问题。

请忽略上面的任何明显错误:我今晚尝试了几种解决方案,因此实际代码已被多次重写。我在记忆中写了以上内容。

我想要的是以下内容:

  • 使用参数运行mount命令,获取其输入和输出流的管道
  • 等待输出管道上的第一个特定问题
  • 通过写入输入管道来回答具体问题
  • 等待输出管道上的第二个特定问题
  • ...等...

等等。

1 个答案:

答案 0 :(得分:0)

您可能会发现Kernel#system有用。它打开一个子shell,所以如果你没事,用户只是直接与mount交互,这将使一切变得更容易。