86開発合宿3日目日記

朝2時頃、眠たくなってお風呂にはいっているときに、結局子プロセスがflushしないのが問題であって、Rascutがlogger.rbを使っているのだから、logger.rbをflushするようにしてしまえばいいやと思いついた。人に渡して使ってもらう分には不便だけど、自分が使う分にはとりあえずそれでいいや。

logger.rbの505行目くらいにある

@dev.write(message)

の後ろに

@dev.flush

と書き足す。これで出力がフラッシュされるようになる。

これで子プロセスの出力にErrorという文字列が含まれていた場合にマリオが死んだ音を鳴らすスクリプトが動くようになった。近いうちに音じゃなくてgrawlにする。

        • -

frsyukiにそれはttyを挟めばいいんだと教えてもらう。面倒そうだと思ってスルーしていたのだけど、rubyで書かれたソースを見たら30行程度だったのでなんだ簡単だと。pythonのライブラリリファレンスを改めてひっくり返して見ているとptyってモジュールがある。これを使えばいいようだ。

        • -

合宿も終わりに近づいて12時チェックアウトまでの中だるみ

        • -

成田の駅でSuicaの処理をしてもらう必要があったのだけど列が長かったので先に出てコンビニでお茶をかって戻ってきたら誰もいなくなっていた。解散したか。

        • -

成田は観光地らしい。せっかく来たし急いでもいないから行ってみるか。





何て読むのかな?

すごい




丸い!

残念ながら受付は締め切り済みでした

帰り道がわからない。

煎餅屋で売っていたにんにく煎餅がかなりおいしい。

        • -

歩いている間は暑かったのだけど駅で風に吹かれていたら寒い。

ヤバい、電車間違えた。芝山千代田とかにいる。

        • -
>>> import pty
>>> pty.spawn(["sed","s/a/b/g"])
aaa
bbb
abc
bbc

簡単じゃん!

        • -
>>> def foo(*args, **kw):
...     print args, kw
...     return "hoge"
... 
>>> pty.spawn("cat", foo)
hoge(7,) {}
(以下ループ)

おおっと。raiseしておけばよかった。慌ててctrl+cした。なるほどねー。

>>> def foo(fileno):
...     import os
...     data = os.read(fileno, 1)
...     print repr(data)
...     return data
... 
>>> pty.spawn("cat", foo)
'a'
   a'b'
       b'c'
           c'^'
               ^'D'
                   D'\x08'
                         '\x08'
                              'a'
                                 a'b'
                                     b'c'
                                         c'^'
                                             ^'D'
                                                 D'\x08'
                                                       '\x08'
                                                            ''
                                                              ''
                                                                ''
                                                                  ''
(以下ループ)

むう。

import pty
import os
import sys

class LineBuffer(object):
    def __init__(self):
        self.buf = []
    def __call__(self, fileno):
        c = os.read(fileno, 1)
        if c == "\n":
            line = "".join(self.buf)
            if "Error" in line:
                c = "!\n"
            self.buf = []
        else:
            self.buf.append(c)

        return c

pty.spawn(["sed", "s/l/r/g"], LineBuffer())
$ python mytty.py
abc
abc
all
arr
Ellolaaa
!rroraaa
 aaa
aaa

ちょっとだけ期待と違う動きをしている。ターミナルに対して"\n"を出力しても、stdout.write("\n")したような挙動にはならないわけか。名前通りキャリッジリターンとラインフィードの二つセットで表示位置が制御されていて、ラインフィードが来たときに"!\n"と表示するようにしたせいでキャリッジリターンが先に行われて行の頭に書き込まれてしまっている。さっきの上の例で^Dを表示した後0x08(BS)が2回送られていたのも、試してみると確かにその通り^Dが表示された後カーソルが2文字戻って^Dの頭に来ていた。"\n"じゃなくて"\x0D"(CR)を見ればいいわけだな。

$ python mytty.py
abc
abc
all
arr
Ellol
Error!

ばっちり!

家についた。7時。眠い。