1

我有 Ruby programA 调用 Ruby programB :

 system("ruby programB.rb <parameters>")

在某些情况下,我希望 programB 终止其操作(以及相关的子 shell),但允许 programA 继续执行下一组参数。

但是,exit()abort()杀死子外壳和父外壳,我无法Process.kill("SIGTERM",0)在 programB 中工作(不幸的是,这是在 Windows 上)。我正在运行 ruby​​ 1.9.2。

如何在不杀死程序A的情况下终止程序B?

4

3 回答 3

3

如果常规system呼叫没有削减它,通常的方法是执行以下操作:

pid = fork do
  exec("ruby programB.rb ...")
end

kill("SIGTERM", pid)

fork操作为您提供了一个可以终止的进程标识符。system将阻塞直到子进程返回,因此kill在父进程中的任何调用都只会影响父进程。

不幸的是fork,Windows 中没有,但有一些替代方案可以实现相同的目标。

于 2012-12-22T01:48:00.807 回答
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将不起作用。Open3.capture3如果您需要知道返回了什么状态代码,或者 STDERR 是否返回任何内容,我建议您使用。

于 2012-12-22T03:22:29.030 回答
0

对我来说唯一可靠的是:

kill -INT $$

它可靠地杀死脚本并且只杀死脚本,即使它是从命令行获取的。请注意,我正在运行 GNU bash,版本 4.4.12(1)-release (x86_64-apple-darwin15.6.0);我不记得这是否适用于 bash 3.x

于 2017-05-30T13:45:12.580 回答