O problema é que o Prompt de Comando do Windows / Interpretador de Linha de Comando (CLI),
conhecido como CMD.EXE, tem um bug (bem, eu tenho certeza que a Microsoft acha que é um recurso) em que,
quando lê uma construção de bloco como IF … ( … )
ou FOR
loop,
ele interpreta todas as variáveis %variable_name%
imediatamente , antes que o loop seja executado.
No seu exemplo, se ans
for nulo quando você inserir o bloco IF %ERRORLEVEL% NEQ 0 ( … )
,
então todas as ocorrências de %ans%
dentro desse bloco são avaliadas como nulas,
mesmo se você alterar ans
dentro do bloco.
Você pode ver isso se você deixar ECHO
on (ou ligá-lo novamente antes de IF %ERRORLEVEL% NEQ 0
).
A correção é dizer ao CMD para permitir que as variáveis sejam expandidas no momento certo, quando as declarações referentes a eles são executadas. Você faz isso adicionando
setlocal enabledelayedexpansion
em algum lugar perto do início do seu arquivo de lote e alterando o código da caixa de diálogo do usuário para que pareça
set /p ans=Do you want to retry %~2 [y/n]^>
if "!ans!" == "y" goto :retry
if "!ans!" == "Y" goto :retry
usando o formulário !variable_name!
para ativar a expansão atrasada.
Veja SET /?
e SETLOCAL /?
para mais informações.