外部プログラムとの連系

Rubyから別のプログラムを起動し,そのプログラムが 出力するものを受け取ったり,そのプログラムにシグナルを送って 制御したりする例を示す。

mpg123.rb

#!/usr/bin/env ruby

frame = ""
music = ARGV[0] || "hoge.mp3"
t = Thread.new do
  # child process
  STDERR.printf("ちわ,子です。%s を演奏します。\n", music)
  require 'open3'
  command = sprintf("mpg123 -v %s", music)
  i, o, e = *Open3.popen3(command)
  while not e.closed?
    line = ""
    while l = e.getc
      if l != ?\r
	line << l.chr
      else
	# STDERR.print line+"\r"
	break
      end
    end
    if /Frame\#\s*(\d+)/ =~ line
      STDERR.printf "%s ", $1 if $DEBUG
      frame = $1.to_i
    end
  end
end
# 以下や親スレッドのみが実行
while true
  STDERR.print "cmd(qで終了): "
  a = STDIN.gets
  if a.nil? || /q/ =~ a
    Thread.kill t
    break
  end
end
printf "Stopping at frame %s\n", frame

本日の目次

yuuji@e.koeki-u.ac.jp