標準入力からの読み取り

set /p を使えば、sh の read 相当のことが出来るのではないかと思い、

@echo off
setlocal
:loop
set /p X=
if not %ERRORLEVEL% == 0 goto :eof
echo "%X%"
goto loop

と書いてみる(zz.bat)。
set /p で ^Z を入れると ERRORLEVEL が 1 になることは別途確認済み。
コンソールからの入力はOK。^Z でちゃんと終わる。

echo AAA | zz

もOK。

dir | zz

だとおかしい。2行しか表示されないし、やる度に表示される行が違う。
どうもパイプでの同期が取れていない模様。
たまたまタイミングがあったdirの結果行が取り込まれた結果と思われる。

P.S.
もしかして^Cのチェックが入力を食っているのかと、break off に期待したが、
WinXPの場合はbreakコマンドが無効とのことで駄目。