Nic*_*ner 2 ruby io kill process popen
我有一个启动子进程的Ruby脚本.我希望他们在整个过程被杀死时被杀死.
IO.popen('testacular start unit.conf.js', 'w')
Run Code Online (Sandbox Code Playgroud)
运行我的脚本:
user.name:/my/repo [git: my-branch] $ ruby my-script.rb
Run Code Online (Sandbox Code Playgroud)
来自testacular的输出:
user.name:/my/repo [git: my-branch] $ info: Testacular server started at http://localhost:8000/
info (launcher): Starting browser PhantomJS
info (PhantomJS 1.7): Connected on socket id uVAO41Q2niyLA8AqbZ8w
PhantomJS 1.7: Executed 44 of 44 SUCCESS (0.213 secs / 0.115 secs)
Run Code Online (Sandbox Code Playgroud)
点击Control-C来杀死进程.检查正在运行的进程:
user.name:/my/repo [git: my-branch] $ ps
PID TTY TIME CMD
# ...
39639 ttys019 0:01.28 node /usr/local/bin/testacular start unit.conf.js
39649 ttys019 0:00.09 node /usr/local/bin/phantomjs /var/folders/2p/dklw3xys2n3f4hqmx73zvz6w0000gp/T/testacular-61981618/capture.js
39650 ttys019 0:00.82 /usr/local/lib/node_modules/phantomjs/lib/phantom/bin/phantomjs /var/folders/2p/dklw3xys2n3f4hqmx73zvz6w0000gp/T/testacular-61981618/capture.js
Run Code Online (Sandbox Code Playgroud)
我们可以看到testacular进程仍在运行.
手动杀死它,看看典型的testacular关闭输出:
user.name:/my/repo [git: my-branch] $ kill 39639
info: Disconnecting all browsers
error (launcher): Cannot start PhantomJS
user.name:/my/repo [git: my-branch] $
Run Code Online (Sandbox Code Playgroud)
有没有办法IO.popen打电话,以便我以后不必手动杀testacular?
是的,您只需要在主进程中安装一个信号处理程序来捕获Ctrl-C(SIGINT),然后将该信号发送到子进程.
这个例子应该解释一下:
# Start child and save its pid
io = IO.popen("sleep 600")
pid = io.pid
# Print the output of the ps command (just for demonstration)
puts "Checking #{pid} ..."
system("ps #{pid}")
puts "Installing signal handler..."
Signal.trap("INT") {
# Ctrl-C was pressed...
puts "Caught interrupt - killing child..."
# Kill child process...
Process.kill("INT", pid)
# This prevents the process from becoming defunct
io.close
# Just for demonstration purposes - check that it died
puts "Checking #{pid} ..."
system("ps #{pid}")
# Forward the INT signal back to the parent
# ...or you could just call "exit" here too.
puts "Forwarding signal to myself..."
Signal.trap("INT", "DEFAULT")
Process.kill("INT", 0)
}
# Make the parent "do some stuff"...
puts "Sleeping parent..."
sleep 600
Run Code Online (Sandbox Code Playgroud)
输出:
> ruby popen_test.rb
Checking 2474 ...
PID TTY STAT TIME COMMAND
2474 pts/0 S+ 0:00 sleep 600
Installing signal handler...
Sleeping parent...
# Press Ctrl-C ...
Caught interrupt - killing child...
Checking 2474 ...
PID TTY STAT TIME COMMAND
Forwarding signal to myself...
kill.rb:20: Interrupt
from kill.rb:24:in `call'
from kill.rb:24:in `sleep'
from kill.rb:24
Run Code Online (Sandbox Code Playgroud)