PHPが言うことを聞かない

ゆえあって、PHPで簡単なスクリプトを書いているのだが、これが動かない。

今回のプロジェクトには、SCMとしてSubversionを投入することに成功している。Subversionのアカウントファイルは、CVS同様apacheのhtpasswdを利用して作るのだが、何十人分ものアカウントを追加するのに、ひとつひとつコマンドを叩くのも面倒だ。そこで、htpasswdをアカウント数分叩くラッパースクリプトが欲しくなるのは自然なことである。

UNIX環境であればシェルスクリプトPerlで実装するのだが、相手はWindows Server 2003であり、そんな便利なものは入っていない。cmdの貧弱さは目に余るものがあり、とてもじゃないが使えない。ところが、Mantis Bug Trackerを動かす都合上、PHPは入れてあるのだ。これを使うのが良いだろう。

処理は簡単だ。アカウント情報をCSV形式で受け取り、これを解析してhtpasswdに渡す、ただそれだけ。ちょっとしたエラー処理を組み込んでも、大した手間にはならない。問題はPHPに全然慣れていないことだが、相手はLightweight Languageである、ちょっと入門サイトを覗けば書けるはずだ。

だいたい30分ぐらいかけて、動くものができあがる。実行!

'C:\Program' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

きたよ・・・。ApacheがC:\Program Filesに入っているからねぇ。まったく、Microsoftは何を考えてスペース入りのフォルダ名にしたんだか。ならば、コマンド文字列に適切にダブルクォーテーションを打ち込めば回避できるはず。

$command = sprintf("\"%s\" %s %s %s %s", HTPASSWD, $option, $passwdfilepath, $account[0], $account[1]);

ほら、動いた。しかし、待てよ?$passwdfilepathだって、ファイルパスである以上、スペースが含まれた形になることもある。ここにも同じ処置をせねば・・・。

$command = sprintf("\"%s\" %s \"%s\" %s %s", HTPASSWD, $option, $passwdfilepath, $account[0], $account[1]);

完璧。

'C:\Program' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

なに!?
ダブルクォーテーション追加したところ、コマンド自身とは関係ないところじゃんか・・・。なぜ動きが変わってしまうのかわからん。

今日はここまでで挫折。

そもそもApacheのインストール先を変えて、スペース入りパスを使用禁止とすれば解決するのだが、それは敗北である。今回限りの使い捨てならばよいが、今後別の保守担当者が触るかもしれない。Windowsが放っておけばProgram Filesに入れてしまう以上、今後もこの問題はつきまとうわけで、そのとき後任が首を捻ることになりかねない。ここでちゃんと作っておくべきであろう。闘いは続く。

それにしても・・・謎の動きをするPHPを恨むべきか、迷惑なフォルダ名をつけたMicrosoftを罵倒すべきなのか・・・。