Решение уже предоставлено этим ответом .Тем не менее, я хочу показать вам, как я написал бы код, чтобы сделать его максимально безопасным от всех комбинаций всех видов специальных символов, используя правильные кавычки, включая и применяя отложенное расширение только там, где это действительно необходимо, и отключая его там, где это необходимо.это тревожно или небезопасно:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem /* No delayed expansion during immediate variable assignment,
rem so escaping of exclamation marks is not required;
rem quotation in a way not to become part of the value: */
set "foo=Argument -> Not provided!"
setlocal EnableDelayedExpansion
rem /* Delayed expansion during reading of variable;
rem quote argument value here to protect white-spaces: */
call :output_actual_error "!foo!"
endlocal
endlocal
exit /B 0
:output_actual_error
rem /* No delayed expansion during argument expansion (%);
rem quotation in a way not to become part of the value: */
setlocal DisableDelayedExpansion
set "bar=%~1"
setlocal EnableDelayedExpansion
rem // Delayed expansion during reading of variable:
echo(!bar!
endlocal
endlocal
exit /B 0
Это в основном позволяет избежать отложенного расширения во время присваивания переменной и%-расширения и использует отложенное расширение всякий раз, когда переменная читается.
По-прежнему сохраняются риски сбоя:
- Один вводится
call
, потому что он удваивает кавычки (^
). - Другой представлен расширением аргумента (
%~1
), которое можетвызвать проблемы с кавычками, особенно когда они кажутся несбалансированными.