cmd の静的変数展開の問題が発生しています。MODE 変数は一度だけ評価されます。@echo off 行を省略すると、これを確認できます。
セットから /? ドキュメンテーション:
最後に、遅延環境変数展開のサポートが追加されました。このサポートは、デフォルトでは常に無効になっていますが、CMD.EXE への /V コマンド ライン スイッチを介して有効/無効にすることができます。CMD /? を参照してください。
遅延環境変数展開は、テキスト行が実行されたときではなく、読み取られたときに発生する現在の展開の制限を回避するのに役立ちます。次の例は、即時変数展開の問題を示しています。
set VAR=before
if "%VAR%" == "before" (
set VAR=after
if "%VAR%" == "after" @echo If you see this, it worked
)
両方の IF ステートメントの %VAR% は、複合ステートメントである IF の本体を論理的に含むため、最初の IF ステートメントが読み取られるときに置換されるため、メッセージは表示されません。したがって、複合ステートメント内の IF は、実際には「前」と「後」を比較していますが、これは決して等しくなりません。同様に、次の例は期待どおりに動作しません。
set LIST=
for %i in (*) do set LIST=%LIST% %i
echo %LIST%
現在のディレクトリにファイルのリストを作成するのではなく、代わりに LIST 変数を最後に見つかったファイルに設定するという点で。繰り返しますが、これは、FOR ステートメントが読み取られるときに %LIST% が 1 回だけ展開され、その時点で LIST 変数が空であるためです。したがって、実行している実際の FOR ループは次のとおりです。
for %i in (*) do set LIST= %i
LIST を最後に見つかったファイルに設定し続けるだけです。
遅延環境変数展開では、別の文字 (感嘆符) を使用して、実行時に環境変数を展開できます。遅延変数展開が有効になっている場合、上記の例は次のように記述して意図したとおりに動作させることができます。
set VAR=before
if "%VAR%" == "before" (
set VAR=after
if "!VAR!" == "after" @echo If you see this, it worked
)
set LIST=
for %i in (*) do set LIST=!LIST! %i
echo %LIST%