web-dev-qa-db-ja.com

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

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

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
101
user1530318

ドキュメント から:

コマンドは、終了ステータスがゼロの場合は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
158
Stefan

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

$のいくつかの便利な方法オブジェクト:

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

systemは、コマンドにゼロ以外の終了コードがある場合はfalseを返し、コマンドがない場合はnilを返します。

だから

system( "foo" ) or exit

または

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

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

24
Neil Slater

system呼び出しの結果をキャプチャしていないため、結果コードが返されます。

exit_code = system("Ruby test.rb")

Backtickメソッドを含む各system呼び出しまたは同等のものは新しいシェルを生成するため、以前のシェルの環境の結果をキャプチャすることはできません。この場合、exit_codeは、すべてがうまくいけばtrue、そうでなければnilです。

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

6
tadman

これを行う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
4
the Tin Man