For循环中的Errorlevel(批处理窗口)

22 windows batch-file errorlevel

我有以下Windows批处理代码:

for %%i in (iidbms iigcc iigcd dmfacp dmfrcp rmcmd qwerty) do (
  tasklist | findstr /i %%i
  echo %errorlevel%
  if %errorlevel% == 0 (echo %%i ok process found %errorlevel%)
  if %errorlevel% == 1 (echo %%i no process found %errorlevel%)
)
Run Code Online (Sandbox Code Playgroud)

但它没有像我期望的那样起作用.

所有名称进程iidbms,iigcc,iigcd,dmfacp,dmfrcp,rmcmd都是真实的,并且找到了它们,而qwerty是一个发明的,不应该找到它,所以应该打印"no process found 1",但它不会,它总是打印0.

但我所注意到的是,如果我tasklist | findstr /i qwerty从dos提示符运行,就在有%errorlevel%= 1之后.

什么样的答案可能或更好?

Tim*_*ell 28

setlocal EnableDelayedExpansion
Run Code Online (Sandbox Code Playgroud)

到脚本的开头,然后使用 !errorlevel!而不是%errorlevel%

延迟扩展将导致变量在执行时而不是在解析时扩展

~ http://ss64.com/nt/delayedexpansion.html

另一个问题的答案指出了我正确的方向:https://stackoverflow.com/a/6658935/10245


JRL*_*JRL 27

如果返回码等于或高于指定的errorlevel,则IF ERRORLEVEL返回TRUE.在您的示例中,由于0小于1,因此如果实际错误代码为0或更高,则第一个errorlevel语句将始终为true.你想要的是首先测试errorlevel 1.

例如:

for %%i in (iidbms iigcc iigcd dmfacp dmfrcp rmcmd qwerty) do (
    tasklist | findstr /i %%i
    if errorlevel 0 if not errorlevel 1 echo process
    if errorlevel 1 if not errorlevel 2 echo process not found
)
Run Code Online (Sandbox Code Playgroud)

另一个问题是,如果要在for循环内回显实际的错误级别.由于变量在循环开始之前被解析,因此回显%errorlevel%将始终回显0.如果要在执行时回显该值,则需要修改代码段,如下所示:

setlocal enabledelayedexpansion
for %%i in (iidbms iigcc iigcd dmfacp dmfrcp rmcmd qwerty) do (
    tasklist | findstr /i %%i
    if errorlevel 0 if not errorlevel 1 echo %%i ok process found !errorlevel!
    if errorlevel 1 if not errorlevel 2 echo %%i no process found !errorlevel!
)
Run Code Online (Sandbox Code Playgroud)