I have Ruby programA that calls Ruby programB with:

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

Under certain conditions, I want programB to terminate its operation (and the associated subshell) but allow programA to continue on to the next set of parameters.

However, exit() and abort() kill both the subshell and the parent, and I am unable to get Process.kill("SIGTERM",0) to work in programB (unfortunately, this is on Windows). I'm running ruby 1.9.2.

How can I terminate programB without also killing programA?

有帮助吗?

解决方案 3

The only thing that works reliably for me is this:

kill -INT $$

It reliably kills the script and only the script, even if it was source'd from the command line. Note that I'm running GNU bash, version 4.4.12(1)-release (x86_64-apple-darwin15.6.0); I can't recall if this works on bash 3.x

其他提示

If the regular system call isn't cutting it, the usual way is to do something like this:

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

kill("SIGTERM", pid)

The fork operation gives you a process identifier you can kill. system will block until the child process returns, so any call to kill in the parent process will affect only the parent process.

Unfortunately there's no fork in Windows, but there are alternatives that achieve the same thing.

exit() and abort() don't kill the parent, at least not on Mac OS, and Linux in my experience.

Try saving this as abort.rb:

puts RUBY_VERSION
puts `date`
puts 'aborting'
abort

and this as exit.rb:

puts RUBY_VERSION
puts `date`
puts 'exiting'
exit

Then save this as test.rb in the same directory and run it:

puts `ruby exit.rb`
puts `ruby abort.rb`

On my system I see:

1.9.3
Fri Dec 21 22:17:12 MST 2012
exiting
1.9.3
Fri Dec 21 22:17:12 MST 2012
aborting

They do exit the currently running script in the sub-shell, which then exits because it's not a log-in shell, and could set a return status which is important to the calling program, but I have yet to see them kill the parent.

If you need to capture STDERR, using backticks or %x won't work. I'd recommend using Open3.capture3 for simplicity if you need to know what status code was returned, or whether STDERR returned anything.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top