该命令的语法不正确。在endlocal&设置[批次]

时间:2015-04-14 05:47:52

标签: windows batch-file cmd

我有一个函数,它通过批量引用返回值。

:errorCheck
setlocal
set "test_command=%~1"
set "err_code=%~2"
FOR /F "delims=" %%a IN ('%test_command% 2^>^&1 1^>NUL') DO (
set err_msg="%%~a"
)
if [%err_msg%] neq [] (
    if not x%err_msg:%err_code%=%==x%err_msg% (
        set "error=true"
    )
)   

if [%err_msg%]==[] (
     set "error=false"
)
endlocal & set "%3=%error%"
exit /b

该函数正确执行且返回值也正确但在执行endlocal & set "%3=%error%"部分时在行set "%3=%error%"处它给出了错误:

The syntax of the command is incorrect.

我无法理解为什么它会发生,尽管返回值是正确的。

1 个答案:

答案 0 :(得分:3)

问题不在返回值中,而是在子字符串操作中。不允许使用您的语法。表达式不会按您的意思进行评估。变量的开始和结束是

%err_msg:%err_code%=%
^........^        ^.^
var1              var2

要在另一个变量的子字符串操作中使用变量,您需要使用延迟扩展。试试

:errorCheck
    setlocal enableextensions disabledelayedexpansion
    set "test_command=%~1"
    set "err_code=%~2"
    set "error=false"
    set "err_msg="

    FOR /F "delims=" %%a IN ('
        %test_command% 2^>^&1 1^>NUL
    ') DO set "err_msg=%%~a"

    if defined err_msg (
        setlocal enabledelayedexpansion
        if not "!err_msg:%err_code%=!"=="%err_msg%" (
            endlocal
            set "error=true"
        ) else ( endlocal )
    ) 

    endlocal & set "%3=%error%"
    exit /b

现在解析器看到的变量是

!err_msg:%err_code%=!
         ^........^
^...................^

但由于在子标记操作中不允许所有字符,取决于err_code的内容,它可能也会失败。

如果可能是这种情况,您可以将子字符串操作更改为管道命令,搜索所需的错误代码

:errorCheck testCommand errorCode returnVariable
    setlocal enableextensions disabledelayedexpansion
    ( %~1 2>&1 1>nul | find "%~2" > nul ) && ( set "error=true" ) || ( set "error=false" )
    endlocal & set "%~3=%error%"
    exit /b

那是:

  • 执行命令(%~1),与原始代码一样,stdout重定向到null,stderr重定向到stdout,因此我们读取错误流。
  • 使用find过滤命令的输出,搜索错误代码。如果找到,find将不会引发错误级别,如果找不到,则会引发错误级别。
  • 使用条件执行,设置error变量。如果上一个命令没有引发errorlevel,则执行&&之后的代码。如果命令引发了errorlevel,则执行||之后的代码。
  • 恢复环境空间并返回变量asigned