2013-01-31 63 views
2

有一個IO.popen命令被殺死。我希望他們在整個過程中喪生時被殺害。從testacular我有一個啓動子的Ruby腳本時,呼叫者進程被終止

user.name:/my/repo [git: my-branch] $ ruby my-script.rb 

輸出:

IO.popen('testacular start unit.conf.js', 'w') 

運行我的腳本

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) 

按下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 

我們可以看到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] $ 

有沒有一種方法,使IO.popen電話,這樣我就不必手動殺testacular以後呢?

回答

5

是的,你只需要在你的主進程陷阱按Ctrl-C(SIGINT)安裝signal handler,然後發送信號給子進程。

這個例子應該解釋的事情:

# 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 

輸出:

> 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 
+0

真棒,謝謝! –

相關問題