Правила пакетного выхода довольно неприятны, но поведение полностью предсказуемо, если вы знаете правила.
Сведения, необходимые для понимания проблемы, доступны по адресу Как интерпретатор сценариев команд Windows (CMD.EXE) анализирует сценарии? на этапах 1, 2, 5 и 6 принятого ответа. Но удачи, поглощающей эту информацию в ближайшее время :-)
Есть две фундаментальные проблемы проектирования, которые приводят к вашей проблеме:- Фаза 6 удваивает все каретки, а затем перезапускает фазу 2 (фактически фазы 1, 1.5 и 2).
- Но фаза 2 требует &
быть экранирована как ^&
. Обратите внимание, что это должен быть один ^
, а не удвоенный!
Единственный способ добиться вашего подхода к работе - ввести ^
после того, как на этапе 6 произошло удвоение каретки.
@echo off
setlocal enableDelayedExpansion
set "ESC=^"
rem Calling with delayed expansion value
set "val=with%%ESC%%&ersand"
call :Output !val!
rem Calling with a string literal
call :Output with%%ESC%%^&ersand
exit /b
:Output
set "line=%1"
echo Called: !line!
goto :eof
ESC определяется для проведения ^
.
Первый раунд фазы 1 расширяет %%ESC%%
до %ESC%
второй раунд фазы 1 (инициированный фазой 6) расширяет %ESC%
до ^
Это все абсолютно непрактично, особенно если вы не знаете, каким будет контент.
Единственная разумная стратегия для надежной передачи любого значения в процедуру CALLed - это передача по ссылке. Передайте имя переменной, содержащей строковое значение, и разверните это значение в подпрограмме, используя отложенное расширение.
@echo off
setlocal enableDelayedExpansion
set "val=with&ersand"
call :Output val
exit /b
:Output
set "line=!%~1!"
echo Called: !line!
exit /b