遅延環境変数のechoの謎

環境変数echoするとき、値が空かも知れないときに、「ECHO は です。」等と表示されないために、echo. 等とするのは基本的なTIPSである。私はピリオドを好んで使っていたが、他の記号を好む人もいるようだ。今まで特に問題は無かったが、遅延環境変数で、部分文字列や文字列置換を使うと不都合が起こるようだ。

@echo off
setlocal enabledelayedexpansion
set A=abcdefg
echo !A!
echo !A:~1!
echo !A:~1,3!
echo !A:~10!
echo !A:~10,3
echo !A:*d=!
echo !A:*g=!
echo ...................
echo.!A!
echo.!A:~1!
echo.!A:~1,3!
echo.!A:~10!
echo.!A:~10,3!
echo.!A:*d=!
echo.!A:*g=!
echo ===================
echo=!A!
echo=!A:~1!
echo=!A:~1,3!
echo=!A:~10!
echo=!A:~10,3!
echo=!A:*d=!
echo=!A:*g=!

表示結果は

abcdefg
bcdefg
bcd
ECHO は <OFF> です。
ECHO は <OFF> です。
efg
ECHO は <OFF> です。
...................
abcdefg
bcdefg
A:~1,3

A:~10,3
A:*d=
A:*g=
===================
abcdefg
bcdefg
bcd


efg

となる。

echo. だと長さを指定した部分文字列や文字列置換を使った時に意図しない表示となっている。echo=echo,echo; だと問題ない。この3文字は、

for %%A in (A=B;C,D) do echo %%A

のように、for文の(セット)の部分で、各要素の区切りに使える文字列だ。どの文字も echo の直後に書くのは違和感があるが、このように空になる可能性のある遅延環境変数の展開ではこの3つのうちどれかを使わざるを得ないであろう。

バグなのか仕様なのか微妙なところだが、遅延展開でなければピリオド等でも問題ないのと比べると仕様が異なるのは意図不明なので仕様と強弁するのは困難だろう。まあ、アンドキュメントな部分ではあるが。