[python][unix] リダイレクションやパイプの有無を識別する方法
リダイレクションやパイプを使用している場合は読み込み、使用してない場合はヘルプを表示するなど、
切り替えたい場合は次のように書くのがいいのかな。
import os import sys if os.isatty(os.sys.stdin.fileno()): print_usage() sys.exit(1) # 標準入力をすべて読み込む for line in sys.stdin: sys.stdout.write(line)
リダイレクションやパイプと、端末の入力を同時に行う方法
お題
リダイレクションやパイプからデータを読み込んだ上で端末の入力を読み込む、
そんなプログラムを書こうとしてはまったので整理。
イメージ:
$ echo hoge foo bar | ./to_upper_case_and_xxx.py HOGE FOO BAR input: <- 端末からなにか入力
この場合、次のように書きたくなります。
import sys # 標準入力をすべて読み込む for line in sys.stdin: sys.stdout.write(line.upper()) # 端末の入力を読み込む result = raw_input('input: ') print '>> ' + result
しかし、EOFErrorが発生してうまくいきません。
$ echo hoge | ./raw_input_test.py ... EOFError: EOF when reading a line
raw_input()が内部でsys.stdinを参照しているので、読みきってると動かないわけですね。
それに読み込み元がリダイレクションやパイプになっているため、このままではインタラクティブな操作はできません。
ではどうするか
実行例 | 標準入力 | |
---|---|---|
通常 | ./program.py | /dev/tty |
パイプ | echo hoge | ./program.py | echoの出力 |
リダイレクション | ./program.py < path/to/file | /path/to/file |
通常、標準入力は/dev/ttyになっており、端末の入力はこの特殊なファイルから読み込んでいます。
これが、パイプやリダイレクションを利用した場合、別プログラムの出力やファイルに差し替わります。
/dev/ttyをオープンすれば端末からの入力を受け取れるので、sys.stdinに割り当ててみましょう。
修正版
というわけで、次のように変更します。
import os import sys # 標準入力をすべて読み込む for line in sys.stdin: sys.stdout.write(line.upper()) # TTY (/dev/tty) をオープンして、標準入力に割り当てる sys.stdin = file('/dev/tty') # TTYを割り当てたので、端末の入力を読み込める result = raw_input('input: ') print '>> ' + result
今度はちゃんと動作しますね。
もちろん、raw_input()を使わずに直接TTYから読み込んでもOKです。
tty = file(os.ctermid()) sys.stdout.write('input: ') result = tty.readline() print '>> ' + result
はてなブログはじめました!
それだけ!
Gitでコミットをやり直す方法 (パッチ編)
う〜ん、困った。
あるコミットはUTF-8、またあるコミットはEUC-JPでログを書くなんて…。
修正しようにも
$ git rebase -i
では文字化けてしてまってうまくいかない。
ちょっと大げさかもしれないけど、次の方法で修正する。
既存コミットのパッチに書き出す
第1引数にはパッチを作成し始めるコミットを指定する。
今回はすべて書き出すのでmasterを指定。
$ git format-patch master
コマンドを実行するとその場にパッチを作成しようとするので要注意。
patchesなど適当なディレクトリに移動しておくべし。
問題のパッチを修正
さて、以下のようなパッチファイルができた。
$ ls -1 0001-FIXME-xxx-xxx-xxx.patch 0002-FIXME-xxx-xxx-xxx.patch 0003-FIXME-xxx-xxx-xxx.patch 0004-FIXME-xxx-xxx-xxx.patch 0005-FIXME-xxx-xxx-xxx.patch 0006-FIXME-xxx-xxx-xxx.patch 〜 略 〜
中身はメールと同じ書式で、コミットログとファイルの差分が含まれる。
ここでは、問題のあるコミットログを修正する。
新しいブランチにパッチを適用
まずはパッチを適用する新しいブランチを作成、チェックアウト。
masterからのパッチなのでmasterを元にする。
$ git branch new_branch master $ git checkout new_branch
最後にamコマンドでパッチを適用。
$ git am *.patch
おしまい♪
一般ユーザでscreenが使えない
ServersMan@VPS(CentOS5)で一般ユーザだとscreenが使えない。
Sorry, could not find a PTY.
なんて言われちゃいます。
一般ユーザで screen が動かない - プログラマ 福重 伸太朗 〜基本へ帰ろう〜によると
/dev/ptmxのパーミッションが足りないようだ。
$ ls -la /dev/ptmx crw-r--r-- 1 root root 5, 2 2?? 13 12:43 /dev/ptmx
なのでグループとその他に書き込み権限を与えてあげる。
# chmod 0666 /dev/ptmx # ls -la /dev/ptmx crw-rw-rw- 1 root root 5, 2 2?? 13 12:43 /dev/ptmx
するとちゃんと動いた♪
MacBook Air 11インチ欲しい!
めっちゃほしい!