如何从命令结果中获取 for /f 循环中的错误级别?

问题描述 投票:0回答:2

我正在批处理文件中运行 SQL 请求,我需要获取错误级别及其给出的输出。我尝试过使用:

for /f "tokens=*" %%i in ('%SQLCommand%') do ( ...

在“do”中,如果错误级别为1,那么我可以执行我计划执行的任何操作,但我似乎无法找到从命令结果中获取错误级别的方法。我也不确定错误级别在循环中是否可以改变,但我计划对其进行测试,这样我就可以知道命令是否会改变错误级别。

batch-file errorlevel
2个回答
3
投票

这里的问题是分配给环境变量

SQLCommand
的命令行由FOR在后台的单独命令进程中使用
cmd.exe /C
执行,其处理STDOUT的输出由FOR捕获并处理行按行。因此,无法在执行批处理文件的命令进程中评估 SQL 命令行的退出代码。

最可能的最佳解决方案是在当前命令进程中运行 SQL 命令行,将 SQL 命令行的输出重定向到临时文件,评估退出代码并根据退出代码处理输出。

下面的批处理文件演示了此解决方案。它可以在没有参数的情况下启动,使用有效的文件/文件夹名称作为第一个参数,或者使用无效的文件/文件夹名称来监视错误处理。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "OutputFile=%TEMP%\%~n0.tmp"

if "%~1" == "" ( set "DirArg=%TEMP%" ) else set "DirArg=%~1"
set "SQLCommand=dir /A /B "%DirArg%""

%SQLCommand% >"%OutputFile%" 2>nul
echo/

if errorlevel 1 (
    echo An error occurred on execution of command:
    echo/
    echo %SQLCommand%
    echo/
    echo Exit code is: %ERRORLEVEL%
    goto EndBatch
)

echo Execution of command was successful. The output is:
echo/

for /F "usebackq delims=" %%I in ("%OutputFile%") do echo %%I

:EndBatch
del "%OutputFile%"
endlocal
echo/
pause

为了了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • del /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • set /?
  • setlocal /?

另请参阅 Stack Overflow 问题:


0
投票

可以用

%ERRORLEVEL%
获得
for /f
,正如
aschipfl
在评论中指出的那样,但这很棘手,我在 dostips.com 论坛上找到了
this
,现在我得到了命令中的错误号,因此使用该代码作为基础我做了这样的事情:

@echo off
setlocal EnableDelayedExpansion

for /f "tokens=*" %%i in ('%command% ^|^| call echo ERROR_NUMBER%%^^^^errorlevel%%') do (
    set OutputLine=%%i
    if /i "!OutputLine:~0,12!" == "ERROR_NUMBER" (
        set ERRNB=!OutputLine:ERROR_NUMBER=!
        echo The error number was: !ERRNB!
    )
)

请注意,我使用的是

EnableDelayedExpansion
%command%
只是将要执行的命令,
^|^|
用于转义
pipes
字符,并在上一个命令失败时执行,剩下的就是一种方法要在 dostips.com 论坛
%%^^^^errorlevel%%
中获取错误号
Dave Benham
说这只是一个
hack
:

它并不是真的在逃避什么。这是一个推迟了的黑客行为 变量的扩展。

请记住,在命令行上下文中,%DoesNotExist% 的结果 是%不存在%。另请记住,任何字符之前都有插入符号 结果该字符被保留。它不一定是一个 特殊字符。

在扩展过程中插入符号被视为变量名称的一部分 阶段。假设我们有一个名为“myVar”的变量。然后一个命令 像 call echo %^myVar% 这样的行语句,尝试扩展变量 CALL 之前有“%^myVar%”,但它不存在。然后插入符是 删除(m 被保留),剩下 %myVar%。然后 在 CALL 之后,它会再次尝试并正确扩展正确命名的 变量。

当然,如果存在名为“^myVar”的变量,上述操作将会失败。但 插入符号通常不用于变量名称。

戴夫·贝纳姆

© www.soinside.com 2019 - 2024. All rights reserved.