【问题标题】:popen3 hangs when executing script with popen3使用 popen3 执行脚本时 popen3 挂起
【发布时间】:2016-06-24 01:18:23
【问题描述】:

我有下一个代码

 def execute_bash(cmd)
  puts "Executing: [#{cmd}]"
  exit_code = Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
    stdin.close
    stdout.each { |line| puts line }
    stdout.close
    stderr.each { |line| puts line }
    stderr.close
    wait_thr.value.exitstatus
  end
  return exit_code
end

我使用此函数运行的命令是 vagrant up,它会产生大量输出。我有很多食谱,所以我需要逐行实时监控它的输出。

我还有另一个脚本可以确保之前的脚本运行良好并且没有崩溃。所以我有另一个脚本,它以与以前相同的方式运行 bash 命令。所以我喜欢跑步(在第二个脚本中):

execute_bash "./vagrant_up.rb"

这样的后果导致我死锁或其他东西:在某些时候输出停止。我可以等待很长时间,但它不会继续。

当我在控制台中运行 vagrant - 一切都很好。

在另一个popen3中运行带有popen3的ruby脚本有问题吗? 是否有处理popen3中死锁的正确方法(如果是死锁,我不确定)?

【问题讨论】:

    标签: ruby bash output deadlock


    【解决方案1】:

    如果不查看 vagrant_up.rb 的详细信息,很难说真正的问题是什么,但请考虑以下内容。

    这里有一个小 bash 脚本:

    #!/bin/sh
    #out.sh
    echo "about to sleep"
    sleep 3
    echo "just woke up"
    

    还有一个:

    #!/bin/sh
    #err.sh
    echo "about to sleep" 1>&2
    sleep 3
    echo "just woke up" 1>&2
    

    使用您的代码,运行execute_bash("out.sh") 产生的结果可能符合您的期望。它说“要睡觉”,然后 3 秒后它说“刚醒来”。但是,运行execute_bash("err.sh") 确实有点令人惊讶。它等待 3 秒,然后打印“即将睡觉”和“刚醒来”。

    所以,对于你的情况,这是我的猜测。您的命令可能会为 stderr 生成大量输出,而您只是没有看到它。实际上,在命令完成之前您不会看到它(因为 Open3 进程的标准输出流直到那时才会关闭)。

    你能把标准错误重定向到标准输出吗?如果这不能解决问题,您能否发表评论?

    execute_bash("./vagrant_up.rb 2>&1")
    

    【讨论】:

    • 不幸的是,重定向 stderr 并没有帮助。 system() 函数会发生同样的死锁吗?
    猜你喜欢
    • 2012-02-15
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 2012-07-27
    相关资源
    最近更新 更多