【问题标题】:Errorlevel in a For loop (batch windows)For 循环中的错误级别(批处理窗口)
【发布时间】:2010-10-15 12:37:32
【问题描述】:

我有以下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%)
)

但它并没有像我预期的那样工作。

所有名称进程iidbmsiigcciigcddmfacpdmfrcp, rmcmd 是真实的,并且它们是被发现的,而 qwerty 是一个发明的,不应该找到它,所以应该打印 " no process found 1",但不是,它总是打印 0。

但我注意到的是,如果我在 dos 提示符下运行 tasklist | findstr /i qwerty,则紧随其后的是 %errorlevel% = 1。

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

【问题讨论】:

    标签: windows batch-file errorlevel


    【解决方案1】:

    添加

    setlocal EnableDelayedExpansion
    

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

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

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

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

    【讨论】:

      【解决方案2】:

      如果返回代码等于或高于指定的错误级别,则 IF ERRORLEVEL 返回 TRUE。在您的示例中,由于 0 小于 1,因此如果实际错误代码为 0 或更高,则第一个 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
      )
      

      另一个问题是,如果您想从 for 循环中回显实际的错误级别。由于变量是在循环开始之前解析的,所以回显%errorlevel%总是回显0。如果要在执行时回显该值,则需要像这样修改sn-p:

      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!
      )
      

      【讨论】:

      • 我颠倒了顺序(先是 1,然后是 0),但结果是一样的
      • 如果您没有更改发布的代码,那么您需要在错误级别 1 之后使用 goto 来跳过下一条语句,或者更改您的条件(使用 NEQ 等)。
      • 我真的认为你写的很对。但我不明白为什么在代码的另一部分行:unloaddb.exe -c test > abc.txt, if %errorlevel% equ 0 call :backup, if %errorlevel% equ call :no_backup, 工作正常.. ..
      • 我测试了你的第二个例子,效果很好。你知道为什么我在上面添加的评论 (:backup, :no_backup) 有效吗?
      • 代码为:unloaddb.exe -c test > abc.txt;如果 %errorlevel% equ 0 调用 :backup;如果 %errorlevel% equ 1 调用 :no_backup;或者你更喜欢我写它的意思是“回答你的问题”......?
      【解决方案3】:

      你可以使用vbscript,

      NumArgs = WScript.Arguments.Count
      strComputer="."
      Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
      Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process")
      For Each objProcess in colProcessList
          For i=0 To NumArgs-1
              If InStr( objProcess.Name ,WScript.Arguments(i)  ) > 0 Then
                  WScript.Echo "found:" & WScript.Arguments(i)
              End If 
          Next 
      Next
      

      用法:

      C:\test>cscript //nologo test.vbs explorer spool svchost
      found:svchost
      found:svchost
      found:svchost
      found:svchost
      found:svchost
      found:explorer
      found:svchost
      found:spool
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多