为什么中断使用system
调用创建的子ruby进程不会中断ruby进程本身?它们应该属于同一组,所以都应该被打断。这在ruby2.0中也无效。
给定ruby 1.8.7补丁371,ruby 1.9.3补丁392和ruby2.0补丁0:
在bash中运行ruby1.8 -e 'system "sleep 100"; p $?; sleep'
并按下ctrl C只会杀死对sleep 100
的内部调用。
Ruby 1.9的行为相同。
虽然运行ruby2.0 -e 'system "sleep 100"; p $?; sleep'
会中断内部命令和ruby进程。2.0.0-p0
——编辑——
阅读资料,我发现处理SIGINT
, SIGQUIT
和SIGHUP
在rb_syswait
方法中切换到忽略,而不是等待创建的子进程完成,然后恢复处理程序(rb_syswait
在ruby v1.8.7-p370, ruby v1.9.3-p362中没有阻塞ruby v2.0 -p0中的处理程序)。
为什么只对system
和IO.popen
这样做,而不是%x{}
或fork{}
?
作为一种变通方法,您可以自己传播SIGINT。您可以检查系统命令是否由于信号而退出,如果是,则引发SIGINT:
ruby1.8 -e 'system "sleep 100"; p $?; Process.kill("INT",0) if $?.signaled?; sleep'
这似乎不是Ruby的问题,而是您没有指定的操作系统的问题。进程分组和底层系统路由由OS内核完成。