O principal problema é que, além da variável de loop, cmd expande variáveis em um loop de arquivo em lote antes que o loop seja executado, portanto, embora A esteja sendo definido dentro do loop, o valor ecoado é anterior para entrada no loop (ou seja, em branco). Você pode ver que o valor foi definido omitindo o set antes do final echo : a saída será a mesma.
A resposta é ativar Expansão atrasada e use !A! em vez de %A% .
A propósito, os comandos copy e echo no início do arquivo são uma maneira desnecessariamente longa de escrever echo firstLine > %1 .
Assim, seu arquivo em lote funcionará como esperado se você modificá-lo da seguinte maneira: -
@echo off
SetLocal EnableDelayedExpansion
rem copy NUL %1
rem echo firstLine >> %1
echo firstLine > %1
echo /=======================/
for /l %%x in (1,1,3) do (
echo %%x
set /p A=< %1
echo !A!
)
echo /=======================/
rem set /p A=< %1
echo %A%
Observe que você estará definindo A para o mesmo valor em cada passagem do loop. Você precisará usar uma técnica diferente se quiser que cada passagem mostre linhas sucessivas do arquivo.