0

我想知道如何从Open3.popen3Ruby 上捕获异常。

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] $
4

0 回答 0