Ruby: systemで終了ステータスをチェックして例外を投げる


よく使うのでスニペット的にメモ。

def _system(cmd)
  $stderr.puts "command=#{cmd}"
  system cmd
  status = $? # Process::Status
  unless status.success?
    raise "abnormal exit status (status=#{status.exitstatus} pid=#{status.pid})"
  end
end

(2019-03-20 追記)

下記のオプションが追加されたので、 2.6 以降の場合はこのオプションを使うと良さそう。

Ruby 2.6先行チェック: Kernel#systemに`exception:`オプションが追加(翻訳)
https://techracho.bpsinc.jp/hachi8833/2018_08_24/60356

Ruby 2.6のKernel#systemではexception: trueオプションが使えるようになったので、上のように明示的なraiseによるスクリプト停止コードを書かなくて済むようになりました。





(2015-11-08 追記)

system の代わりにバッククォートで実行して標準出力への出力を取得するようにしたもの。

def _system(cmd)
  $stderr.puts "command=#{cmd}"
  out = `#{cmd}`
  status = $? # Process::Status
  unless status.success?
    raise "abnormal exit status (status=#{status.exitstatus} pid=#{status.pid})"
  end
  out
end



(2019-03-20 追記)

配列を渡して Shellwords でエスケープする場合:

require 'shellwords'

def _system(args)
  cmd = Shellwords.shelljoin(args)
  # (snip)
end



(2021-04-21 追記)
Process::Status#to_i ではなく Process::Status#exitstatus を使うように修正しました。