我正在尝试以编程方式产生一个Puma进程,然后通过发送TERM来终止它。
为此,我使用了Process.spawn,它返回一个pid。此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时,外壳进程也会终止,但puma会继续在后台运行。彪马从来不会收到SIGTERM。
puts pid
10711
Process.kill("TERM", pid)
=> 1
Process.wait(pid)有没有其他方法可以在Ruby内部持续地产卵和杀死美洲狮?任何线索为什么衍生的进程没有发送信号给它的子进程(puma)。这是我的操作系统、Ruby或Puma中的错误吗?也许这是预期的行为?
这是我的app.ru https://gist.github.com/schneems/18c216cc159772c80361
发布于 2014-03-04 04:19:42
最快的方法是使用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。
https://stackoverflow.com/questions/22156262
复制相似问题