【问题标题】:Suppress FORFILES "no files found" error抑制 FORFILES“找不到文件”错误
【发布时间】:2013-05-29 17:50:32
【问题描述】:

我正在使用批处理文件来删除超过 14 天的存档文档,并且我正在从读取脚本返回码的自动化进程 (Lansa Composer) 调用该文件以查看是否存在问题.这是脚本:

@echo off
@Echo Deleting files older than 14 days...
cd /d C:\Windows\System32
FORFILES /P "[file path...]\IDOC_ARCHIVE" /M *.* /D -14 /C "cmd /c del @file"

问题是脚本返回一个错误代码并打印“错误:没有找到具有指定搜索条件的文件”,如果它没有找到任何要删除的文件,而我真的只希望它返回一个错误,如果有是访问目录或运行 del 命令等问题。有什么方法可以让这个脚本抑制“找不到文件”错误,但允许其他人通过?

经过一番谷歌搜索后,我尝试了this page 上的解决方案,但它们无法满足我的要求,因为在第一种情况下它会抑制所有错误,而在第二种情况下,错误消息的文本会被传递,但是实际的返回码仍然被抑制(这是自动化过程读取的内容)。

【问题讨论】:

  • 我不知道你需要什么。使用2>nul 抑制错误消息不会删除℅errorlevel%
  • @Endoro 但它是什么类型的错误是不分青红皂白的。我需要一个解决方案,它只会抑制“找不到匹配的文件”错误,而不是其他类型的错误。我实际上根本不关心错误消息(STDERR 或 STDOUT),除了它似乎是区分不同类型的唯一方法。
  • 因此,在 for 循环中捕获错误消息并将其存储在变量中以供进一步分析。
  • 尝试FORFILES /P "[file path...]\IDOC_ARCHIVE" /M *.* /D -14 /C "cmd /c del @file" | find /V "No files found" 应该排除该错误消息,但可能不会影响errorlevel
  • 谢谢@Endoro,成功了。

标签: batch-file


【解决方案1】:

这应该可以解决这个问题:

@echo off
Echo Deleting files older than 14 days...
cd /d C:\Windows\System32
copy /b forfiles.exe "[file path...]\IDOC_ARCHIVE" >nul
FORFILES /P "[file path...]\IDOC_ARCHIVE" /M *.* /D -14 /C "cmd /c del @file"

它的作用是提供超过 14 天的文件 - 因此它将始终被删除,并且不会出现“未找到文件”消息。我选择了 forfiles.exe 进行复制,但您可以使用任何超过 14 天的文件。所有其他错误消息都将正常显示。

【讨论】:

  • 我不确定我是否理解这是在做什么。这不会抑制所有错误吗?
  • 它所做的是提供一个超过 14 天的文件 - 所以它总是会被删除,并且不会出现“找不到文件”消息。我选择了 forfiles.exe 进行复制,但您可以使用任何超过 14 天的文件。所有其他错误消息都将正常显示。
  • 非常好的解决方案,因为它独立于操作系统语言
【解决方案2】:

添加 2>nul 成功了。谢谢!

forfiles /p d:\todayfiles /d +0 /c "cmd /c echo @path" 2>nul |找到 ":" /c

这基本上抑制了该命令的错误流。所以即使在执行此操作时出现了其他错误,也不会出现!

【讨论】:

  • 太棒了!我只想补充一点,这基本上抑制了该命令的错误流。所以即使在执行此操作时出现了其他错误,也不会出现!
【解决方案3】:

解决方案是在 FOR 循环中捕获 FORFILES 命令的输出,在其中搜索以 ERROR 开头的字符串,并将结果存储在变量中。从那里,您可以使用 IF/ELSE 指令相应地设置errorlevel。这是代码(减去一些日志记录和 cmets):

cd /d C:\Windows\System32
SET _CmdResult=NONE
FOR /F "tokens=*" %%a IN ('FORFILES /P "[file path...]\IDOC_ARCHIVE" /M *.* /D -14 /C "cmd /c DEL @file" 2^>^&1 ^| FINDSTR ERROR') DO SET _CmdResult=%%a
IF "%_CmdResult%" == "ERROR: No files found with the specified search criteria." ( 
    SET errorlevel=0 
 ) ELSE ( 
    SET errorlevel=1
 )
IF "%_CmdResult%" == "NONE" SET errorlevel=0

只需确保在 FOR 循环中转义任何字符,例如 >&|

【讨论】:

    【解决方案4】:

    要可靠地影响 ERRORLEVEL,您需要运行一个保证将 ERRORLEVEL 设置为 0 的后续命令。 我使用命令解释器本身 (cmd.exe) 来执行此操作,如下面的 sn-p:

    FORFILES  /M:somefiles /D -14 2>nul | cmd /c ""
    

    希望这对某人有所帮助。

    【讨论】:

      【解决方案5】:

      这很容易用一个衬垫解决。只需将其附加到您的 forfiles 命令:

      2>&1 | find /v /i "ERROR: No files found with the specified search criteria."

      所以你会得到:

      FORFILES /P "[file path...]\IDOC_ARCHIVE" /M *.* /D -14 /C "cmd /c del @file" 2>&1 | find /v /i "ERROR: No files found with the specified search criteria."

      仅不显示指定的错误消息。所有其他消息都是。

      这是如何工作的:

      • 2>&1 用于将 STDERR 发送到我们发送 STDOUT 的same place
      • | find /v /i pipesforfilesfind 的输出,其中/v 表示不包含指定的字符串,/i 表示不区分大小写

      【讨论】:

      • 谢谢,但这不完整。正如我在问题中所说,需要通过或被阻止的部分或错误是 errorlevel 返回码,而不是消息文本。我只关心文本,因为它区分了错误类型。
      【解决方案6】:

      我可以为这个已经很有价值的线程添加一个不起眼的贡献吗?我发现其他解决方案可能会删除实际的错误文本,但忽略了表示我的应用程序失败的 %ERRORLEVEL% 。并且我合法地想要 %ERRORLEVEL%,只要它不是“未找到文件”错误。

      一些例子:

      具体调试和排除错误:

      forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&ECHO found error||echo found success
      

      使用oneliner返回ERRORLEVEL成功或失败:

      forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&EXIT /B 1||EXIT /B 0
      

      使用 oneliner 将 ERRORLEVEL 保持为零,以便在其他代码中间的批处理文件上下文中成功(ver > nul 重置 ERRORLEVEL):

      forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&ECHO found error||ver > nul
      

      对于 SQL Server 代理 CmdExec 作业步骤,我执行了以下操作。不知道是不是bug,但是step里面的CmdExec只能识别第一行代码:

      cmd /e:on /c "forfiles /p "C:\SQLADMIN\MAINTREPORTS\SQL2" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&EXIT 1||EXIT 0"&exit %errorlevel%
      

      【讨论】:

      • 对于 SQL Server 代理 CmdExec 作业,我将“失败时操作”更改为“退出作业报告成功”,因为这是作业的最后一步,我不希望失败报告。
      【解决方案7】:

      尝试在脚本后添加

      2>Nul 
      

      例子

      SET Days=14
      
      FORFILES /S /M *.* /D -%Days% /C "CMD /C DEL @file" 2>Nul
      

      希望对您有所帮助。

      【讨论】:

        【解决方案8】:

        尝试删除分机硬盘上年度备份中的重复项时,我遇到了同样的问题。 在互联网上搜索到的解决方案都没有(添加@path,在命令参数中省略cmd /c)对我有用。系统询问“你确定...”让我想到了以下解决方案:使用 /q 参数。 结果擦除了我 2016 目录中的 2015 文件:

        forfiles /p G:\YearlyBU\Mine\16-12-29\IMeMine\Documents /s /c "cmd /c del @path @file /q"  /d -1100
        

        【讨论】:

          猜你喜欢
          • 2014-01-09
          • 2021-05-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多