バッチファイル。IF文やFOR文の中で複数コマンドを書く時の注意点 - Windowsのコマンドプロンプト(bat,cmd)
○Windows XP
IF 文や FOR 文の中で複数コマンドを実行したい時は、丸括弧(= 小括弧)を使うと便利です。但し、次の時は、書き方を工夫する必要があります。
o IF 文や FOR 文の括弧内で環境変数の代入と参照を行いたい時
o 括弧内で、「"」に括られていない「)」を直接書きたい時
**** 問題となるパターン
o 括弧内で「"」に括られていない「)」を直接記述すると、文法エラーになります。
+ 全角の「)」は大丈夫です。
+ 変数の中に入っている「)」は大丈夫です。
o 次の2つの事を同時に行うと、コマンドプロンプトは予想外の値を返します。
+ 1つの丸括弧(= 小括弧)内で、環境変数に対して値を代入する
+ その括弧内において、代入した環境変数の値を参照する
o この時、参照した環境変数の値は、括弧内で代入する前の値となります。
+ 代入した値が有効になるのは、IF文(やFOR文)を抜けた直後からです。
--------
@echo off
set MIKU=ミクさん
if "%MIKU%"=="ミクさん" (
set MIKU=ミク
echo %MIKU%だよ
)
echo %MIKU%%MIKU%
--------
+ 予想は「ミクだよ」「ミクミク」
+ 結果は「ミクさんだよ」「ミクミク」
**** 問題となる原因
o コマンドプロンプトは、コマンドを1つずつ実行します。
o そして、IF文(やFOR文)は、括弧を含めて1つと解釈します。
o その結果、IF文(やFOR文)の中にある %環境変数% は、全て、IF文(やFOR文)を実行する直前の値で置き換わります。
**** 解決方法
o 3つの方法があります。
+ 参照と代入を別々の文に分けてしまう方法
+ CALL文を使う方法
+ 遅延環境変数を使う方法
** 参照と代入を別々の文に分けてしまう方法
--------
@echo off
set MIKU=ミクさん
if not "%MIKU%"=="ミクさん" goto XMIKU
set MIKU=ミク
echo %MIKU%だよ
:XMIKU
echo %MIKU%%MIKU%
--------
+ 結果は「ミクだよ」「ミクミク」
+ この書き方は、古いパソコンでも動きます。
** CALL文を使う方法
--------
@echo off
set MIKU=ミクさん
if "%MIKU%"=="ミクさん" call :x_call
echo %MIKU%%MIKU%
goto :eof
:x_call
set MIKU=ミク
echo %MIKU%だよ
goto :eof
--------
+ 結果は「ミクだよ」「ミクミク」
+ CALL先に限り、1文ずつ評価される状態になります。
+ 括弧の中から「echo %MIKU%だよ」の部分だけを CALL 文にする事も出来ます = 同じ結果になります。
+ この書き方は、古いパソコンで動くかどうかは分かりません。
+ CALL先をバッチファイルにして、goto :eofを使わなければ、古いパソコンでも動きます。
** 遅延環境変数を使う方法
o 遅延環境変数を使う場合、次の3点で書く方法がお手軽です。
+ setlocal をオプション付き
+ endlocal
+ 遅延評価したい環境変数は「%」の代わりに「!」
o 但し、環境変数の有効範囲が通常よりも狭くなっていますので、気を付けて使います。
+ setlocal の中で代入した環境変数の値は、endlocal やバッチファイルを抜けると元に戻ります。
--------
@echo off
setlocal enabledelayedexpansion
set MIKU=ミクさん
if "%MIKU%"=="ミクさん" (
set MIKU=ミク
echo !MIKU!だよ
)
echo %MIKU%%MIKU%
endlocal
--------
+ 結果は「ミクだよ」「ミクミク」
+ この書き方は、おそらく、Windows NT以前では動きません。
o この他に、コマンドプロンプト cmd.exe を遅延させるオプションを付けて呼び出し、その中で実行させる方法もあります。
**** 確認したバージョン
o Windows XP Service Pack 3
==
関連ページ:
▼Windowsコマンド。制御文と環境変数(▼ABC順)
▼Windowsコマンド一覧(▼ABC順)
▼コマンドプロンプト画面
▼制作メモ
> %変数の使い方
環境変数の使い方。置換と部分文字列
環境変数の生存期間について
+
GOTO = 指定したラベルに移動する
バッチファイルでif文の条件式を書く時の注意点
(2011年3月2日追加。FOR文対応と、CALLを使った回避方法)
(2011年1月30日追加。括弧内で「"」に括られていない「)」)