我想知道如何从Open3.popen3
Ruby 上捕获异常。
require "open3"
begin
Open3.popen3("./somebinary") {|i,o,e,t|
# IO.popen("./somebinary") {|i|
$stderr.puts "popen"
i.puts "some string"
}
rescue StandardError => e
$stderr.puts e.message
$stderr.puts e.backtrace.inspect
$stderr.puts "error"
exit(1)
end
问题是二进制可执行文件的体系结构错误,不能在本地机器上运行。当从命令行调用时,像这样./somebinary
,您会看到错误消息。
使用popen
时,救援子句会捕获错误,但使用 时不会popen3
。
如果rescue
子句没有StandardError => e
,则输入子句,但您无法知道错误的原因,因为您看到的只是来自 的消息“错误” $stderr.puts "error"
。使用popen3
,命令行中的 stderr 消失了!
我在 macOS 11.3.1 上使用 ruby 3.0.1p64 。
一个完整的例子
~/tmp $ ./somebinary
dyld: Library not loaded: /usr/local/opt/gcc/lib/gcc/10/libgfortran.5.dylib
Referenced from: /Users/furue/tmp/./somebinary
Reason: image not found
fish: Job 1, './somebinary' terminated by signal SIGABRT (Abort)
~/tmp [134] $ ruby --version
ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [arm64-darwin20]
~/tmp $ cat try-popen3.rb
require "open3"
begin
Open3.popen3("./somebinary") {|i,o,e,t|
$stderr.puts "in popen . . . "
i.puts "some string"
}
rescue
$stderr.puts "error in rescue . . . "
exit(1)
end
~/tmp $ ruby try-popen3.rb
in popen . . .
~/tmp $ cat try-popen3-standarderror.rb
require "open3"
begin
Open3.popen3("./somebinary") {|i,o,e,t|
$stderr.puts "in popen . . . "
i.puts "some string"
}
rescue StandardError => e
$stderr.puts e.message
$stderr.puts e.backtrace.inspect
$stderr.puts "error in rescue . . . "
exit(1)
end
~/tmp $ ruby try-popen3-standarderror.rb
in popen . . .
~/tmp $ cat try-popen.rb
require "open3"
begin
IO.popen("./somebinary") {|i|
$stderr.puts "in popen . . . "
i.puts "some string"
}
rescue
$stderr.puts "error in rescue . . . "
exit(1)
end
~/tmp $ ruby try-popen.rb
in popen . . .
dyld: Library not loaded: /usr/local/opt/gcc/lib/gcc/10/libgfortran.5.dylib
Referenced from: /Users/furue/tmp/./somebinary
Reason: image not found
error in rescue . . .
~/tmp [1] $ cat try-popen-standarderror.rb
require "open3"
begin
IO.popen("./somebinary") {|i|
$stderr.puts "in popen . . . "
i.puts "some string"
}
rescue StandardError => e
$stderr.puts e.message
$stderr.puts e.backtrace.inspect
$stderr.puts "error in rescue . . . "
exit(1)
end
~/tmp $ ruby try-popen-standarderror.rb
in popen . . .
dyld: Library not loaded: /usr/local/opt/gcc/lib/gcc/10/libgfortran.5.dylib
Referenced from: /Users/furue/tmp/./somebinary
Reason: image not found
not opened for writing
["try-popen-standarderror.rb:5:in `write'", "try-popen-standarderror.rb:5:in `puts'", "try-popen-standarderror.rb:5:in `block in <main>'", "try-popen-standarderror.rb:3:in `popen'", "try-popen-standarderror.rb:3:in `<main>'"]
error in rescue . . .
~/tmp [1] $