質問: ### 前提・実現したいこと バッチファイルに機能を追加しようと、色々仕様を確認していたのですが。 仕様?なのか挙動が不明な部分があり 変数の使い方が間違っているのだとは思うのですが... 仕様など教えて頂けませんでしょうか? ### 発生している問題・エラーメッセージ !val!で比較した場合と%val%で比較した場合のIFの判定結果が違う ``` if !val! equ 2 "false" if %val% equ 2 "true" echo.!val! 2 echo.%val% 2 ``` ### 該当のソースコード ``` setlocal enabledelayedexpansion for /f "tokens=3 delims= " %%i in ('find /V "" /C test.txt') do ( set val=%%i ) if !val! equ 2 ( echo "true" )else ( echo "false" ) if %val% equ 2 ( echo "true" )else ( echo "false" ) ``` test.txt ``` aaa bbb ``` ### 試したこと バッチファイルの文法を調べていた途中ですので、文法の確認程度です ### 補足情報(言語/FW/ツール等のバージョンなど) Windows10での実行結果になります。 よろしくお願いいたします。
回答: `for`の中で参照しているのかと思ったそうでは無いので、これはYouheiSakuraiさんの回答とはちょっと違う原因です。 以下、空白の有無が問題になるので、見やすさのために空白を`_`で表します。 原因は、変数`val`にセットされているのが`2`ではなく`2_`なためです。 `%val%`だと展開されてから`if`の解釈がされますので、`2`と`2`が比較されます。 `!val!`だと`if`の構文解釈をしてから展開されます。つまり普通のプログラミング言語の変数参照と同じで、`2_`と`2`の比較になって、同じでは無いです。 対策としては、 ``` for /f "tokens=3 delims= " %%i in ('find /V "" /C test.txt') do ( set val=%%i) ``` のように代入の右辺の`%%i`の後ろの空白を取れば良いです。 なお、質問タイトルが「動的変数、静的変数」ですが、バッチスクリプトで動的変数というと、`%DATE%`や`%RANDOM%`のように、代入せずにシステムの与える値を参照する変数のことです。ざっくり言うと、参照するタイミングによって値の変わる参照専用の変数です(ざっくりのため若干不正確な説明です)。普通のプログラミング言語だと関数ですね。一方、`set`で代入するのが静的変数です。