从 Ruby 生成一个“守护进程”进程,当 Ruby 退出时,该进程不会退出

问题描述 投票:0回答:1

我想从 Ruby 生成一个进程 mycmd:

  1. 我希望 Ruby 能够阻塞,直到 mycmd 将 BOOTED 写入标准输出。
  2. 当 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?

我尝试过的事情:

  1. Open3.popen3("nohup mycmd")
    # mycmd 使用 ruby 退出
  2. Open3.popen3("mycmd &")
    # mycmd 使用 ruby 退出
  3. Open3.popen3("mycmd > /dev/null 2>&1")
    # ruby 退出时 mycmd 不会退出(是的),但我无法从 stdout 读取数据以等待 BOOTED
ruby popen3
1个回答
0
投票

这里可能的问题是子进程的标准输出流由父进程拥有。一旦父进程被杀死,子进程中的

stdout
stderr
描述符就无效,任何使用它们的尝试都会失败,并出现错误,例如:

Broken pipe @ rb_io_flush_raw - <STDOUT>

由于听起来您正在尝试将子进程作为守护进程启动,因此最好避免尝试直接捕获子进程的

stdout
stderr
。正如 Casper 在评论中提到的,将子进程
stdout
stderr
设置为文件是合理的,这也可以通过
STDOUT.reopen(...)

在子进程中完成
© www.soinside.com 2019 - 2024. All rights reserved.