批量 - 逃避大于号不起作用

时间:2018-06-09 21:40:42

标签: batch-file cmd scripting windows-scripting

在下面的脚本中,我将一个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字符串?

2 个答案:

答案 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

这基本上避免了变量赋值和%扩展期间的延迟扩展,并且每当读取变量时都使用延迟扩展。

仍然存在失败的风险:

  1. 一个由call引入,因为它引用了引用的插入符号(^)。
  2. 另一个由参数扩展(%~1)表示,这可能会引起报价问题,特别是当它们看起来不平衡时。