【问题标题】:Using !ERRORLEVEL! in code block piped to another process使用 !ERRORLEVEL!在通过管道传输到另一个进程的代码块中
【发布时间】:2021-02-16 10:04:09
【问题描述】:

为什么!ERRORLEVEL! 在以下示例中不起作用?

@echo off
setlocal enabledelayedexpansion
(
  winscp.com /?
  echo !ERRORLEVEL!
) | findstr /v "word"
exit

我在输出中得到!ERRORLEVEL!

如果我删除 | findstr /v "word":

@echo off
setlocal enabledelayedexpansion
(
  winscp.com /?
  echo !ERRORLEVEL!
)
exit

我得到了输出的错误级别。

【问题讨论】:

    标签: windows batch-file exit-code errorlevel


    【解决方案1】:

    这是因为管道在新的 cmd.exe 实例中执行双方(当命令是批处理命令时)。

    命令/代码块被转换并用作 cmd.exe 的参数,在您的示例中它变为:

    C:\WINDOWS\system32\cmd.exe /S /D /c"( winscp.com & echo !errorlevel!)"
    

    但在调用新的cmd.exe实例时,默认禁用延迟扩展。

    您还可以使用cmdcmdline 伪变量检查行为。

    @echo off
    (
      echo %%cmdcmdline%%
      echo !ERRORLEVEL!  
    ) | findstr /n "^"
    

    演出:

    1:C:\WINDOWS\system32\cmd.exe /S /D /c" ( echo %cmdcmdline% & echo !ERRORLEVEL! )"
    2:!ERRORLEVEL!

    更多信息Why does delayed expansion fail when inside a piped block of code?

    在带有管道的代码块中使用 errorlevel

    你可以简单地使用另一种扩展方法

    (
      winscp.com /?
      call echo %%ERR^^ORLEVEL%%
    ) | findstr /v "word"
    

    显然,这是因为转换后的块看起来像

    C:\WINDOWS\system32\cmd.exe  /S /D /c" ( winscp.com /? & call echo %ERR^ORLEVEL%  )" 
    

    在 cmd.exe 解析块后,百分比扩展已经完成,块看起来像

    ( winscp /? & call echo %errorlevel% )
    

    插入符号在这里很重要,以避免在行执行之前发生扩展。

    另一种解决方案

    创建您自己的 cmd.exe 实例并启用延迟扩展

    (
      winscp.com /?
      cmd /V:on /c echo !SOME_VARIABLE!
    ) | findstr /v "word"
    

    但这仅适用于“普通”变量,不适用于 ERRORLEVELcmdcmdline,因为它们会通过启动新实例而更改

    使用子批处理文件

    您可以使用批处理文件,而不是在管道左侧使用代码块,这样可以再次启用延迟扩展。

    我正在使用蹦床功能,将完整的代码放入一个批处理文件中。

    @echo off
    FOR /F "tokens=3 delims=:" %%X in ("%0") do goto :%%X
    
    "%~d0\:myblock:\..\%~pnx0" | findstr /v "word"
    exit /b
    
    :myblock
    setlocal enabledelayedexpansion
    (
      winscp.com /?
      echo !ERRORLEVEL!
    )
    exit /b
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      • 2018-08-18
      • 2018-12-03
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      相关资源
      最近更新 更多