我有Ruby programA,它用:
调用Ruby programB system("ruby programB.rb <parameters>")
在某些情况下,我希望programB终止其操作(以及相关的子shell),但允许programA继续使用下一组参数。
然而,exit()
和abort()
同时杀死了子shell和父级,我无法让Process.kill("SIGTERM",0)
在programB中工作(不幸的是,这是在Windows上)。我正在运行ruby 1.9.2。
如何在不杀死programA的情况下终止programB?
答案 0 :(得分:3)
如果常规的system
电话没有削减它,通常的方法是做这样的事情:
pid = fork do
exec("ruby programB.rb ...")
end
kill("SIGTERM", pid)
fork
操作为您提供了可以杀死的进程标识符。 system
将阻止子进程返回,因此对父进程中的kill
的任何调用都只会影响父进程。
不幸的是,Windows中没有fork
,但有alternatives可以达到同样的效果。
答案 1 :(得分:2)
exit()
和abort()
不会杀死父级,至少不会杀死Mac OS和Linux。
尝试将其另存为abort.rb
:
puts RUBY_VERSION
puts `date`
puts 'aborting'
abort
这是exit.rb
:
puts RUBY_VERSION
puts `date`
puts 'exiting'
exit
然后将此test.rb
保存在同一目录中并运行它:
puts `ruby exit.rb`
puts `ruby abort.rb`
在我的系统上,我看到:
1.9.3
Fri Dec 21 22:17:12 MST 2012
exiting
1.9.3
Fri Dec 21 22:17:12 MST 2012
aborting
他们确实退出子shell中当前运行的脚本,然后退出因为它不是登录shell,并且可以设置一个对调用程序很重要的返回状态,但是我还没有看到它们被杀掉父母。
如果你需要捕获STDERR,使用反引号或%x
将无效。如果您需要知道返回了什么状态代码,或者STDERR是否返回了任何内容,我建议您使用Open3.capture3
来简化。
答案 2 :(得分:0)
对我来说唯一可靠的是:
kill -INT $$
它可靠地杀死脚本并且只杀死脚本,即使它是来自命令行的源代码。请注意,我正在运行GNU bash,版本4.4.12(1)-release(x86_64-apple-darwin15.6.0);我不记得这是否适用于bash 3.x