0
0

More than 1 year has passed since last update.

[Ruby] system() で stdout, stderr を得る。

Last updated at Posted at 2013-12-07

Open3.capture() をつかえば、外部コマンド実行結果の stdout, stderr, 実行ステータスは得られる。
しかし コマンド実行で stdout, stderr に大量に出力される可能性がある場合、この方法ではメモリーを圧迫してしまう危険がある。

そこで、出力結果をメモリーに展開せずに、 stdout, stderr を得る方法を検討してみた。

発想としては、

  • system() を使う。system() の return 値で実行ステータスを判定する。
  • stdout, stderr はファイルにリダイレクトする。必要に応じて、ファイルの中身を参照する。

以下にコードを書いてみた。 ( ruby 1.9.3-p484)
このコード例では、 system() の return 値は 常に true か falseになる。
( リダイレクトをしないなら、 該当コマンドが無い時などは nil が返るのだが )
このコード例では、該当コマンドが無い時は、false が返り、stderr に "command not found" が記録される。

call_system.rb
def call_system(command)
  stdout_txt = 'stdout.txt'
  stderr_txt = 'stderr.txt'

  ret = system "#{command} 2> #{stderr_txt} 1> #{stdout_txt}"
  if ret
    puts "# --- success [#{command}]"
  else
    puts "# --- error [#{command}]"
  end
  puts "# --- srdout: #{`wc -l #{stdout_txt}`.to_i} line(s), srderr: #{`wc -l #{stderr_txt}`.to_i} line(s)"

end

commands = [
  'ls -algt /',       # success
  'xxxx -algt ~',     # error
  "ruby -e 'exit 0'",  # success
  "ruby -e 'exit 1'",  # error
  "ruby -e 'exit 2'",  # error
  "ruby -e '100.times{puts \"1\"; warn \"2\\n\"};0'", # success
]

commands.each do |c|
  puts '# =========================='
  call_system(c)
end

実行結果は次のようになる。

 ruby call_system.rb
# ==========================
# --- success [ls -algt /]
# --- srdout: 41 line(s), srderr: 0 line(s)
# ==========================
# --- error [xxxx -algt ~]
# --- srdout: 0 line(s), srderr: 1 line(s)
# ==========================
# --- success [ruby -e 'exit 0']
# --- srdout: 0 line(s), srderr: 0 line(s)
# ==========================
# --- error [ruby -e 'exit 1']
# --- srdout: 0 line(s), srderr: 0 line(s)
# ==========================
# --- error [ruby -e 'exit 2']
# --- srdout: 0 line(s), srderr: 0 line(s)
# ==========================
# --- success [ruby -e '100.times{puts "1"; warn "2\n"};0']
# --- srdout: 100 line(s), srderr: 200 line(s)
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0