質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

Q&A

解決済

2回答

5811閲覧

バッチファイルでの変数の取り扱いについて(動的変数、静的変数の判定の違い)

friedaji

総合スコア11

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

0グッド

1クリップ

投稿2017/10/18 09:45

###前提・実現したいこと

バッチファイルに機能を追加しようと、色々仕様を確認していたのですが。
仕様?なのか挙動が不明な部分があり
変数の使い方が間違っているのだとは思うのですが…
仕様など教えて頂けませんでしょうか?

###発生している問題・エラーメッセージ

!val!で比較した場合と%val%で比較した場合のIFの判定結果が違う

if !val! equ 2 "false" if %val% equ 2 "true" echo.!val! 2 echo.%val% 2

###該当のソースコード

bat

1setlocal enabledelayedexpansion 2for /f "tokens=3 delims= " %%i in ('find /V "" /C test.txt') do ( set val=%%i ) 3if !val! equ 2 ( 4 echo "true" 5)else ( 6 echo "false" 7) 8if %val% equ 2 ( 9 echo "true" 10)else ( 11 echo "false" 12)

test.txt

text:test.txt

1aaa 2bbb

###試したこと
バッチファイルの文法を調べていた途中ですので、文法の確認程度です

###補足情報(言語/FW/ツール等のバージョンなど)
Windows10での実行結果になります。

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

forの中で参照しているのかと思ったそうでは無いので、これはYouheiSakuraiさんの回答とはちょっと違う原因です。

以下、空白の有無が問題になるので、見やすさのために空白を_で表します。
原因は、変数valにセットされているのが2ではなく2_なためです。
%val%だと展開されてからifの解釈がされますので、22が比較されます。
!val!だとifの構文解釈をしてから展開されます。つまり普通のプログラミング言語の変数参照と同じで、2_2の比較になって、同じでは無いです。

対策としては、

DOS

1for /f "tokens=3 delims= " %%i in ('find /V "" /C test.txt') do ( set val=%%i)

のように代入の右辺の%%iの後ろの空白を取れば良いです。

なお、質問タイトルが「動的変数、静的変数」ですが、バッチスクリプトで動的変数というと、%DATE%%RANDOM%のように、代入せずにシステムの与える値を参照する変数のことです。ざっくり言うと、参照するタイミングによって値の変わる参照専用の変数です(ざっくりのため若干不正確な説明です)。普通のプログラミング言語だと関数ですね。一方、setで代入するのが静的変数です。

投稿2017/10/18 13:18

otn

総合スコア84505

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

friedaji

2017/10/19 01:42

回答ありがとうございます。 変数と=の間にスペースを含んではならないというのは確認していたのですが まさか後ろのスペースもそのまま代入されてしまうとは… ご提示のとおりの修正で、両方の判定が正しくtrueになるのを確認できました。 空白についてはうっかり入れてしまう事が多いので、かなり気を付けないといけないですね… ありがとうございました。
otn

2017/10/19 10:24

括弧は目に見えるからまだましですが、行末の空白もsetされたりechoされたりするので、エディタによっては要注意です。
guest

0

以下の点が通常のプログラミング言語と違って、Windowsバッチで戸惑いを覚える部分です。

  • 基本的に命令はそれ以下のパーセンテージ変数(%val%)が事前に全部評価された後に実行に移る
  • でもそれだとIFやFORのブロック内に従属する命令で変数が扱えないので困る、そこで遅延評価の仕組みが必要になる
  • ビックリマーク変数(!val!)は遅延評価される、つまりIFやFORのブロック内で従属の命令が実行される時に評価される

しかしながらif !val! equ 2!val!は遅延評価の対象ではない(いかなる命令にも従属しないただの条件式の扱い)ので、!val!という文字列と2の比較になります。

一方でif %val% equ 2if 2 equ 2と変数を評価した後に実行されます。

Windowsバッチはの仕様は本当に闇です。私の回答ももしかしたら間違いがあるかもしれないので、その点は悪しからずご了承ください。

投稿2017/10/18 12:19

YouheiSakurai

総合スコア6142

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

friedaji

2017/10/18 12:47

なるほど… ややこしいですね… 「遅延評価」というキーワードで調べ直してみます。 ありがとうございます
YouheiSakurai

2017/10/18 12:52

expansionなので正確な日本語は遅延展開かもしれません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問