読者です 読者をやめる 読者になる 読者になる

ハチロク世代開発合宿

ハチロク世代開発合宿に参加してきました。分散ファイルシステムを作る、Ruby版Partty!サーバーを作る、温泉に入る、道に迷うなどしてきました。


id:nishiohirokazuさんにインスパイアされて、「何かのコマンドが標準出力に"Error"と出力したら音を鳴らす」というプログラムをRubyで書いてみました。

  • cmdwatch.rb
require 'pty'
require 'thread'


def line_proc(line)
  case line
  when /error|no/i
    # クリボーにやられるなどする
    system("mplayer ./sound/orz.mp3 >/dev/null 2>&1 &")
  when /ok|success|yes/i
    # コインをゲットしたりする
    system("mplayer ./sound/ktkr.mp3 >/dev/null 2>&1 &")
  end
end


if ARGV.empty?
  command = ENV['SHELL'] || "/bin/sh"
else
  command = ARGV.map{|a| "'#{a}'" }.join(" ")
end


BUFSIZ = 2048

begin

  # ptyを作成
  PTY.spawn(command) {|r, w|

    # ターミナルサイズ
    #rows = nil
    #cols = nil

    # コマンド -> 出力 側
    Thread.start(r) {|r|
      outbuf = ""
      linebuf = ""
      while true
        r.sysread(BUFSIZ, outbuf)

        $stdout.write outbuf   # 自前でechoする
        $stdout.flush

        # ターミナルサイズを設定
        #system("stty rows #{rows}") if rows
        #system("stty cols #{cols}") if cols

        # 自前で行単位バッファリングする
        if posn = outbuf.rindex("\n")        # 改行を発見したら...
          linebuf << outbuf.slice!(0..posn)  # 改行より前の部分を取り出して
          linebuf.each_line {|line|          # 1行ずつline_procに渡す
            line.chomp!
            line_proc(line)
          }
          linebuf.replace(outbuf)  # 改行より後の部分はバッファリング
        else
          linebuf << outbuf
        end
      end
    }

    # 入力 -> コマンド 側
    system("stty raw   2>/dev/null")  # 行単位バッファリングをしない
    system("stty -echo 2>/dev/null")  # echoしない
    begin
      inbuf = ""
      while true
        # 標準入力をそのままptyに流す
        $stdin.sysread(BUFSIZ, inbuf)
        w.write inbuf
        w.flush
        # ターミナルサイズを取得
        #rows, cols = `stty size`.split(" ")
      end
    ensure
      #system("stty -raw 2>/dev/null")   # 行単位バッファリングに戻す
      #system("stty echo 2>/dev/null")   # echoするように戻す
      system("reset")  # 全部リセットする
    end

  }

rescue
  # エラーメッセージを揉み消す
end


使い方:

$ ruby cmdcatch.rb make

音を鳴らすところでmplayerを起動しているのがカッコ悪いですが、これで目的は達成されるのでしょうがない。

これを使って./configureを実行すると、大量のコインがゲットできてハッピーになれます。


swfのデバッグプレイヤー

swfをデバッグするときは、スタンドアロン版(ブラウザのプラグインでない)のデバッグプレイヤーをコマンドラインで実行するのがイケてます。trace()の内容が標準出力に出てきます。
スタンドアロン版のFlash PlayerはFlex SDKのruntimes/playerの中に入っています。

~/self/usr/flex/runtimes/player/mac/Flash\ Player.app/Contents/MacOS/Flash\ Player test.swf