Windowsユーザーならみんなbatファイル好きだよね。 一度ははまるであろう環境変数のスコープについてあれこれをまとめる。
setコマンド
set 一時環境変数名=値
環境変数を一時設定する。 実行したコマンドプロンプト内でのみ有効。 (他のプロセスからは見えない。該当プロセスから立ち上がった子プロセスはスコープを引き継ぐ。コマンドプロンプト落とすと消える。)
ちなみに、ユーザー環境変数とかシステム環境変数といったものを恒久的に変えたければsetx
コマンドを使うそうだ。
setlocalとendlocal
「バッチの中だけでスコープ切りたい!」ってときに使えるコマンド。
set X=outscope setlocal echo %X% rem outscopeと表示される set X=inscope echo %X% rem inscopeと表示される endlocal echo %X% rem outscopeと表示される pause
ブロック内で環境変数更新
皆がはまったであろう罠。
例えば、for
で複数命令実行するときは(
... )
で囲んでブロック化する。
for %%i in ( * ) do ( set FILENAME=%%i echo ファイル名は「%FILENAME%」です )
ところが、上のようにブロック内で環境変数を使った場合、コマンド実行時にfor
~ブロック終わりの)
までが一度評価されて、以下のように展開される。
for %%i in ( * ) do ( set FILENAME=%%i echo ファイル名は「」です )
むごい。
回避方法
回避方法を2つ紹介。
setlocal enabledelayedexpansion
setlocal enabledelayedexpansion
と宣言すれば、遅延環境変数というものが使える。
setlocal enabledelayedexpansion for %%i in ( * ) do ( set FILENAME=%%i echo ファイル名は「!FILENAME!」です )
サブルーチン化
call
で別処理に呼ぶと回避できる。
for %%i in ( * ) do ( call :PRINTNAME %%i ) goto :END :PRINTNAME echo ファイル名は「%1」です exit /b :END pause