1

systemRubyの関数を使ってプログラムを実行しようとしています。プログラムの stdout と stderr をキャプチャする必要があるため、stdout と stderr をファイルにリダイレクトするシェル コマンドを使用しています。重要な要件の 1 つは、プログラムが正常に終了したか、シグナルによって強制終了されたかを判断する必要があることです。

私が見ている奇妙な動作は$?.exited?、プログラムがシグナルによって強制終了された場合でも、stdout と stderr をファイルにリダイレクトするときに当てはまるということです! 問題を示すプログラムを次に示します。

#! /usr/bin/ruby

File.open("bad.c", "w") do |out|
    out.print <<'EOF'
#include <stdio.h>

int main(void) {
    int *p = 0;
    *p = 42;
    printf("%d\n", *p);
    return 0;
}
EOF
end
raise "Couldn't compile bad.c" unless system("gcc -o bad bad.c")

system("./bad");
puts $?.exited?

system("./bad > out 2> err");
puts $?.exited?

このプログラムの出力は

false
true

しかし、私は期待します

false
false

どちらの場合も、プログラムはセグメンテーション違反によって強制終了されるためです。

コマンドruby -vは出力を生成します

ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]

説明や回避策があれば大歓迎です!

4

1 に答える 1

2

2 番目の呼び出しでシェルのリダイレクトを実行しているためsystem()、Ruby はその作業を行うためにシェルを呼び出す必要があります。プログラムが強制終了されても、シェルは問題なく実行されます。

代わりに、Ruby で直接リダイレクトを行うことができます。

system("./bad", out: 'out', err: 'err');
puts $?.exited? # => false

その他のオプションについては、ドキュメントを参照してくださいspawn()- のオプションsystem()は同じ方法で処理されます。

于 2013-11-07T14:29:29.240 に答える