禁止显示 FORFILES "no files found"错误



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

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

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

经过一些谷歌搜索,我尝试了这个页面上的解决方案,但他们不会为我想要的工作,因为在第一种情况下,它会抑制所有错误,在第二种情况下,错误消息的文本被传递,但实际的返回代码仍然被抑制(这是自动化过程所读的)。

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

@echo off
Echo Deleting files older than 14 days...
cd /d C:WindowsSystem32
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天的文件。

添加2> null就成功了。谢谢!

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

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

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

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

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

cd /d C:WindowsSystem32
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循环中的任何字符,如>&|

这很容易用一行代码解决。只需将此附加到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的相同位置。
  • | find /v /i通过管道从forfiles输出,以查找/v表示不包含指定字符串,/i表示不区分大小写

我可以为这个已经很有价值的话题做一点小小的贡献吗?我发现其他解决方案可能会摆脱实际的错误文本,但忽略了%ERRORLEVEL%,这表明我的应用程序失败。我想要%ERRORLEVEL%,只要它不是"No files found"错误。

一些例子:

调试和排除错误:

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

使用在线程序返回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

在批处理文件的上下文中,使用联机器将ERRORLEVEL保持为零表示成功(ver> null将重置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 Agent CmdExec作业步骤,我执行了以下操作。我不知道这是否是一个bug,但是步骤中的CmdExec只识别第一行代码:

cmd /e:on /c "forfiles /p "C:SQLADMINMAINTREPORTSSQL2" /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%

尝试在脚本后添加

2>Nul 

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

希望对你有帮助。

我在尝试删除下一个硬盘上的年度备份副本时遇到了同样的问题。在互联网上搜索到的解决方案(添加@path,在命令参数中省略cmd /c)都不适合我。系统询问"Are you sure…"我想到了以下解决方案:使用/q参数。结果清除我的2016目录:

中的2015文件。
forfiles /p G:YearlyBUMine16-12-29IMeMineDocuments /s /c "cmd /c del @path @file /q"  /d -1100

最新更新