Python スクリプトの引数、 Windows にて
os.name == 'nt' つまり Windows の cmd.exe で Python スクリプトに引数を与えたときの話。 UNIX シェルと違って何もしてくれない(いいすぎ)のにちょっとした怒りを覚えてみたり。普段は気にならないのに今日はなにか変だ。 *.py ぐらい融通利かせてほしいし、~ でホームディレクトリっぽいもの指し示してみたいし、環境変数に %% じゃなくて $ でアクセスしたい。
勢いでキーボードをたたいてみた。
import os import sys import re import glob def nt_glob(args): args_new = [] wildcard = re.compile(ur'\*|\?|\[.*\]') for arg in args: arg = os.path.expanduser(arg) arg = os.path.expandvars(arg) if wildcard.search(arg): pathnames = glob.glob(arg) args_new.extend(pathnames) else: args_new.append(arg) return args_new
*, ?, [] を含まないときには glob.glob に渡さないようにしないとファイルに一致しない引数が消えてしまうので場合分けした。でもまだ問題が。 *.py 与えたとき対応するファイルがないならば UNIX シェルはエラーで止まる。 glob.glob は空のリストが返ってくる。
if not pathnames: sys.stderr.write(u'No Match\n') sys.exit(2)
これを pathnames = glob.glob(arg) の直後に挟むことで対応するファイルがないとき止まるようになった。とりあえず目的達成。
あ、しかし foo.{c,py} なんてのもあったような。クォート、ダブルクォートは? エスケープは? [ とか ] ってファイル名に使えるからエスケープできないとさわれないファイル名が出てくる…。シェルに近づけようとしはじめるとやること多くて終わらない。
{}記法程度なら作る気になるけどそれより先に進むのはなぁ。おとなしく cmd.exe に慣れ親しむか、いまどきの Windows らしく PowerShell つかうか、 cygwin, MSYS ら付属のシェルをつかうかしたほうが無難か。
それとも本気でシェルのモノマネするか?