我想从 Ruby 生成一个进程 mycmd:
我有 Ruby 阻塞,直到 mycmd 写入 BOOTED,但我无法让 mycmd 作为守护进程闲逛。
stdin, stdout, stderr, process_status = Open3.popen3("mycmd --whatever")
puts "Starting mycmd, pid=#{process_status.pid}"
# Block until mycmd prints "BOOTED":
stdout.each_line do |line|
break if line.include?("BOOTED")
end
Process.detatch(process_status.pid)
# And now our ruby process exits, killing mycmd as it dies
# How can I keep mycmd running even when Ruby exits?
我尝试过的事情:
Open3.popen3("nohup mycmd")
# mycmd 使用 ruby 退出Open3.popen3("mycmd &")
# mycmd 使用 ruby 退出Open3.popen3("mycmd > /dev/null 2>&1")
# ruby 退出时 mycmd 不会退出(是的),但我无法从 stdout 读取数据以等待 BOOTED这里可能的问题是子进程的标准输出流由父进程拥有。一旦父进程被杀死,子进程中的
stdout
和 stderr
描述符就无效,任何使用它们的尝试都会失败,并出现错误,例如:
Broken pipe @ rb_io_flush_raw - <STDOUT>
由于听起来您正在尝试将子进程作为守护进程启动,因此最好避免尝试直接捕获子进程的
stdout
或 stderr
。正如 Casper 在评论中提到的,将子进程 stdout
和 stderr
设置为文件是合理的,这也可以通过 STDOUT.reopen(...)
在子进程中完成