%VAR% と !VAR! の違い
◆ %VAR% はコマンド実行前に展開されているので & があると前後で 2 コマンド扱いになる
◆ !VAR! はコマンド実行のときに展開されるので & などが含まれていても大丈夫
◆ プログラムに渡されるときは展開した上でスペース区切りになって渡される
◆ 変数部分はスペースあってもまとめられるわけではない
◆ !VAR! はコマンド実行のときに展開されるので & などが含まれていても大丈夫
◆ プログラムに渡されるときは展開した上でスペース区切りになって渡される
◆ 変数部分はスペースあってもまとめられるわけではない
コマンドプロンプトの遅延展開機能はたまに見かけますがいまいちどうなるのかわかってませんでした
で設定できるものです
それが この記事の内容を試してたときにわかりやすい例がみつかりました
これを実行します
dumparg コマンドはコマンドライン引数を列挙するものです
実行結果はこうなりました
上側は実行前に変数が展開されて
となっています
そのため & が複数コマンドを順番にするための命令として扱われて
の 2 コマンドが実行されます
下側では実行段階ではまだ !LF! です
なので 「foo!LF!bar」 は dumparg の引数として実行されます
ただ 「foo!LF!bar」 が 1 つの引数として扱われて展開されるのではなく展開されたあとにスペース区切りで引数が分割されています
「foo& echo.bar」 が 1 つの引数ではなく 「foo&」 と 「echo.bar」 に分割されています
1 コマンドをパースするまでが遅延されて 引数込みでコマンドが確定したら展開した上でコマンドを実行する(プログラムに引数を渡す)ようですね
setlocal EnableDelayedExpansion
で設定できるものです
それが この記事の内容を試してたときにわかりやすい例がみつかりました
setlocal EnableDelayedExpansion
set LF=^& echo.
dumparg --message foo%LF%bar
dumparg --message foo!LF!bar
これを実行します
dumparg コマンドはコマンドライン引数を列挙するものです
実行結果はこうなりました
C:\Users\user1\Desktop\publish>dumparg --message foo & echo.bar
##dump-start##
* --message
* foo
##dump-end####
bar
C:\Users\user1\Desktop\publish>dumparg --message foo!LF!bar
##dump-start##
* --message
* foo&
* echo.bar
##dump-end####
上側は実行前に変数が展開されて
dumparg --message foo & echo.bar
となっています
そのため & が複数コマンドを順番にするための命令として扱われて
dumparg --message foo
echo.bar
の 2 コマンドが実行されます
下側では実行段階ではまだ !LF! です
なので 「foo!LF!bar」 は dumparg の引数として実行されます
ただ 「foo!LF!bar」 が 1 つの引数として扱われて展開されるのではなく展開されたあとにスペース区切りで引数が分割されています
「foo& echo.bar」 が 1 つの引数ではなく 「foo&」 と 「echo.bar」 に分割されています
1 コマンドをパースするまでが遅延されて 引数込みでコマンドが確定したら展開した上でコマンドを実行する(プログラムに引数を渡す)ようですね