T.MURACHIの日記: バッチファイルなんて嫌いだぁ
# 以下、NT 系のコマンドプロンプトの話であり、MS-DOS ではいくつか違ってくる部分があったりします、ご注意を。
バッチファイルの中でバッチファイルを呼び出すと、呼び出したバッチファイルの中で setlocal が使用されて、呼び出し元で定義した変数が使えなくなってしまうことがあります。
@echo off
setlocal
set vari_a=hogehoge
set vari_b=hugahuga
rem ...
boeboe.bat
rem (ここより以後で、vari_a 、vari_b が使えなくなってしまう)
これを回避するには、通常、バッチファイルの呼び出しに start コマンドを使用するのですが、
start "" /b /wait boeboe.bat
boeboe.bat の中で exit コマンドを適切に呼んでいない場合、boeboe.bat の中の処理が終わったところで一旦処理が中断してしまい、利用者が自分で exit コマンドを叩いてあげないと先に進まない、などという困った現象が起こってしまいます。
当然、boeboe.bat の中に exit コマンドを記述すればよいのですが、 boeboe.bat が書き換えできないファイルである場合はそうも行きません。
そこで、苦し紛れに以下のようなトリックを施してみることにします。
@echo off
setlocal
set vari_a=hogehoge
set vari_b=hugahuga
rem ...
echo boeboe.bat > _run.bat
echo exit /b >> _run.bat
start "" /b /wait _run.bat
よーするにその場で即席のラッパーバッチファイルを作って凌ごうという作戦です。 _run.bat の実行には成功したので、これはうまく行くかと思ったのですが、しかし _run.bat の中で exit コマンドが呼ばれることはなく、結局処理はそこで止まってしまいました。
何故でしょう。 boeboe.bat を再度注意深く検証してみたところ、 boeboe.bat の中でも、更に別のバッチファイルを呼び出していました。どうやら、start 越しに、多重でバッチファイルを呼び出すようなバッチファイルを実行するのは、あんまりうまくないらしいと言うことに、そこでようやっと気付くのです。
で、どうしたか。結局、最後の手段とばかりに、以下の記述であっさり解決してしまいました。
perl -e "`boeboe.bat`"
DOS 時代を潜り抜けた百戦錬磨のベテランプログラマーさんであれば、こんな邪道な方法を使わずとも、もっとうまいやり方を知っていらっさるかもしれません。しかし、今日のことから学ぶべきは、「未知のセオリーに拘るよりは、邪道でも確実な道を選べ」であったのだと、理解することにいたします。
一回実行するのにやたらと時間の掛かる処理だったので、こんな遅い時間になってしまいました。なんだかなぁ。。。
バッチファイルなんて嫌いだぁ More ログイン