rubyシステムコマンドチェック終了コード


106

次のようなルビーのシステムコールがたくさんありますが、それらの終了コードを同時にチェックして、コマンドが失敗した場合にスクリプトが終了するようにしたいと考えています。

system("VBoxManage createvm --name test1")
system("ruby test.rb")

私のようなものが欲しい

system("VBoxManage createvm --name test1", 0) <-ここで、2番目のパラメータは終了コードをチェックし、そのシステムコールが成功したことを確認します。成功しなかった場合は、エラーが発生するか、そのような処理が行われます。

それはまったく可能ですか?

私はこれに沿って何かを試しましたが、それもうまくいきませんでした。

system("ruby test.rb")
system("echo $?")

または

`ruby test.rb`
exit_code = `echo $?`
if exit_code != 0
  raise 'Exit code is not zero'
end


上記の例でexit_codeは、は文字列になります- "0\n"またはのいずれかな"1\n"ので、exit_code != 0常にtrueになります
dgmstuart

回答:


166

ドキュメントから:

trueコマンドがゼロfalse以外の終了ステータスの場合、コマンドがゼロの終了ステータスを返すとシステムは戻ります。nilコマンドの実行が失敗した場合に返されます。

system("unknown command")     #=> nil
system("echo foo")            #=> true
system("echo foo | grep bar") #=> false

さらに

エラーステータスはで確認できます$?

system("VBoxManage createvm --invalid-option")

$?             #=> #<Process::Status: pid 9926 exit 2>
$?.exitstatus  #=> 2

2
そしてその出力(終了コードではなく)を変数に取り込む方法は?
アレックス

Railsコンソールを使用している場合は、これをテストしてください。$の値を失う可能性があることに注意してください。したがって、REPLコマンドの一部としてキャプチャする必要があります [10] pry(main)> system("touch /root/test 2> /dev/null") => false [11] pry(main)> $?.exitstatus => 0 [12] pry(main)> system("touch /root/test 2> /dev/null"); $?.exitstatus => 1
lardcanoe

もう一つの優れたの比較systemバッククォート、、 %x、とexecここに提供:stackoverflow.com/questions/6338908/...
トム・ハリソン

38

私にとって、私は ``を使用してシェルコマンドを呼び出し、$?プロセスのステータスを取得します。$?プロセスステータスオブジェクトです。ステータスコード、実行ステータス、pidなどを含む、このオブジェクトからコマンドのプロセス情報を取得できます。

$のいくつかの便利なメソッド?オブジェクト:

   $?.exitstatus => return error code    
   $?.success? => return true if error code is 0, otherwise false
   $?.pid => created process pid

1
Rubocopの助けを借りて、私はの読みやすいエイリアス$?$CHILD_STATUS
RajaRaviVarma

26

systemfalseコマンドにゼロ以外の終了コードnilがある場合、またはコマンドがない場合に返されます。

したがって

system( "foo" ) or exit

または

system( "foo" ) or raise "Something went wrong with foo"

動作するはずであり、合理的に簡潔です。


6

あなたはあなたのsystem呼び出しの結果をキャプチャしていません、それは結果コードが返される場所です:

exit_code = system("ruby test.rb")

systembacktick-methodを含む各呼び出しまたは同等の呼び出しは新しいシェルを生成するため、以前のシェルの環境の結果をキャプチャすることはできません。この場合exit_codetrue、すべてがうまくいったnil場合、そうでない場合です。

このpopen3コマンドは、より低レベルの詳細を提供します。


2
Open3.capture3この種のタスクに使用する特に簡単な方法です。
ティンマン

6

これを行う1つの方法は、andまたはを使用してそれらをチェーンすること&&です。

system("VBoxManage createvm --name test1") and system("ruby test.rb")

最初の呼び出しが失敗した場合、2番目の呼び出しは実行されません。

これらをラップしif ()てフロー制御を与えることができます:

if (
  system("VBoxManage createvm --name test1") && 
  system("ruby test.rb")
) 
  # do something
else
  # do something with $?
end

これまでのところ、私が達成したいものであり、単純明快です。ありがとう
mochadwi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.