ruby - Process.spawn child 没有收到 TERM

标签 ruby bash shell process

我正在尝试以编程方式生成一个 Puma 进程,然后通过发送 TERM 将其终止。

为此,我使用了返回 pid 的 Process.spawn。这个 PID 不是 puma 进程的 PID,而是生成 puma 的 shell 命令的 PID

pid = Process.spawn "bundle exec puma test/fixtures/app.ru -w 3 -t 1:1 -p 0 -e development > test/logs/puma_1961_1393875906.917352.log"
=> 10711

现在我可以运行 ps aux | grep puma 我可以看到它正在运行

schneems        10719   0.0  0.1  2488912   7564 s000  S+    1:57PM   0:00.02 puma: cluster worker: 10712
schneems        10718   0.0  0.1  2488912   7524 s000  S+    1:57PM   0:00.02 puma: cluster worker: 10712
schneems        10717   0.0  0.1  2489936   7652 s000  S+    1:57PM   0:00.02 puma: cluster worker: 10712
schneems        10712   0.0  0.3  2478612  24596 s000  S+    1:57PM   0:00.47 ruby /Users/schneems/.gem/ruby/2.1.1/bin/puma test/fixtures/app.ru -w 3 -t 1:1 -p 0 -e development

但是您会注意到,正如我之前提到的,未列出返回的 PID 10711。它实际上是一个(sh)过程

$ ps -p 10711
  PID TTY           TIME CMD
10711 ttys000    0:00.00 (sh)

现在回到 Ruby 领域。当我尝试通过 Process.kill('TERM', pid) 终止 puma 时,shell 进程终止但 puma 继续在后台运行。 Puma 从不接收 SIGTERM

puts pid
10711
Process.kill("TERM", pid)
=> 1
Process.wait(pid)

是否有另一种方法可以在 Ruby 内部持续生成和杀死 puma?生成进程未向其子进程 (puma) 发送信号的任何线索。这是我的操作系统、Ruby 或 Puma 中的错误吗?也许这是预期的行为?

这是我的app.ru https://gist.github.com/schneems/18c216cc159772c80361

最佳答案

最快的 hack 是使用 exec:

# Bad quick fix
pid = Process.spawn "exec bundle exec puma test/fixtures/app.ru -w 3 -t 1:1 -p 0 -e development > test/logs/puma_1961_1393875906.917352.log"

这会将 shell 替换为调用的进程。

但是,您永远不应将 Process.spawn 与 shell 命令一起使用。当与变量结合时,它会导致令人惊讶、不安全和不可预测的行为。相反,您应该分开参数并自己设置重定向:

# Good solution
pid = Process.spawn("bundle", "exec", "puma", "test/fixtures/app.ru", "-w", "3", "-t", "1:1", "-p", "0", "-e", "development", :out=>"test/logs/puma_1961_1393875906.917352.log")

这首先避免了 shell。

关于ruby - Process.spawn child 没有收到 TERM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22156262/

相关文章:

ruby - Mongoid:如何实现嵌入式文档之间的关系?

Ruby 访问字符串中的单词

bash - 如果函数位于子 shell 内,其行为会如何变化?

linux - MATLAB getenv 无法找到一些 linux 环境变量

linux - 从 .bashrc 脚本中止

ruby - 如何使用 Fog 为云文件设置 Cache-Control header

java - 为什么 Warble 不在 war 文件中包含 .class 文件?

linux - 想使用排序命令在此时间戳 2019-06-29T12 :39:23. 428Z 上对我的日志文件进行排序,但由于有多个定界符而感到困惑

bash - 使用 bash 脚本的输出作为 Terraform 中的变量

bash - 格式化shell脚本日志并写入文件