systemu を使用して Ruby から外部コマンドを実行する

pLaTeX を使うときに、TeX コードのエンコーディングEUC-JP なのに端末の表示エンコーディングUTF-8 だから、メッセージが文字化けしてしまう! → じゃあ Ruby でコマンド実行してメッセージは文字コード変換して端末に表示すればいいじゃない! と思ったのはいいものの、終了コードもとれて、標準出力、エラー出力も使える方法が Ruby 標準機能では難しい模様。

そんなわけで色々探してて見つけたのが ライブラリ systemu です。

早速 RubyGems でインストールして使ってみました。 以下使用例。

#! /usr/bin/ruby1.9
# -*- coding: utf-8 -*-

STDIN .set_encoding( Encoding.locale_charmap )
STDOUT.set_encoding( Encoding.locale_charmap )
STDERR.set_encoding( Encoding.locale_charmap )

require "systemu"

# platex コマンドを実行
res = systemu("platex xxx.tex")

# 標準出力, エラー出力の文字エンコードを EUC-JP だと教えてやる
# (platex に渡しているソースコードが EUC-JP であるため)
res[1].force_encoding("euc-jp") # res[1] は標準出力
res[2].force_encoding("euc-jp") # res[2] はエラー出力

# 終了コード res[0].exitstatus によって処理を変える
# res[0] は Process::Status オブジェクト
if res[0].exitstatus.nil? then
# 誰かが止めた
puts "プロセスは他のプロセスによって止められました"
elsif res[0].exitstatus != 0 then
# 正常に終了しなかった
puts "正常に終了しませんでした"
puts "===== 終了コード ====="
puts res[0].exitstatus
puts "===== 標準出力 ====="
puts res[1]
puts "===== エラー出力 ====="
puts res[2]
else
# 正常に終了した
puts "正常に終了しました"
puts "===== 標準出力 ====="
puts res[1]
puts "===== エラー出力 ====="
puts res[2]
end

exit 0