在下面的脚本中,我将一个qouted字符串传递给子程序并取消引用它(在访问参数时使用代字号)以不加引号输出它。不幸的是,我试图逃避更大的标志并不起作用:
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
set foo="Argument -> Not provided^!"
call :output_actual_error !foo!
ENDLOCAL
EXIT /B 0
:output_actual_error
SETLOCAL DISABLEDELAYEDEXPANSION
set bar=%~1
set bar=%bar:>=^>%
echo %bar%
ENDLOCAL
EXIT /B 0
输出:
Argument - provided!
预期:
Argument -> Not provided!
请注意,该代码仅用于说明,并不代表实际实施。
那么,如何在不使用double的情况下逃避大于号和echo
字符串?
答案 0 :(得分:2)
使用
set "bar=%~1"
set "bar=%bar:>=^>%"
答案 1 :(得分:2)
this answer已提供解决方案。但是,我想向您展示如何编写代码以使其尽可能安全地对付所有类型的特殊字符组合,方法是使用正确的引用并仅在真正需要的地方启用和应用延迟扩展并禁用它这是令人不安或不安全的:
@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
)表示,这可能会引起报价问题,特别是当它们看起来不平衡时。