Ruby の子プロセスの終了ステータスの取得方法
備忘録。
Ruby での子プロセスの終了ステータスの取得方法について、定期的に自分でやらかしたり他の人がやらかしているのを目撃するので書き残す。
Kernel#.system
、バッククォート文字列、もしくは open3
系のメソッドなどで作った子プロセスは $?
で取れる。実態は Process::Status
のインスタンスだが、終了ステータスを $?.to_i
として取ってはいけない。
ドキュメントにある通り、Process::Status#to_i
の返す値は実装依存。終了ステータスを取るなら exitstatus
、終了させたシグナルを取るなら termsig
を使うべきである。
例えば何かしらのプロセスの結果をログに出す時に
system(cmd) log("exit status #{$?.to_i}")
とすると、いざという時に使いものにならず、頭を抱えることになる。こちらの方がいい。
system(cmd) log("exit status #{$?.exitstatus.inspect}, signal #{$?.termsig.inspect}") # nil を明示するために inspect