我有一个函数,它通过批量引用返回值。
: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.
我无法理解为什么它会发生,尽管返回值是正确的。
答案 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,则执行||
之后的代码。