Malcolm
Malcolm

Reputation: 576

Suppress FORFILES "no files found" error

I'm working with a batch file to delete archived documents older than 14 days, and I'm calling the file from an automation process (Lansa Composer) that reads the return code of the script to see if there was a problem. Here's the script:

@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"

The issue is that the script returns an error code and prints "ERROR: No files found with the specified search criteria" if it doesn't find any files to delete, when I really only want it to return an error if there is a problem accessing the directory or running the del command, etc. Is there some way I can get this script to suppress the "no files found" error, but allow others to pass through?

After some Googling I tried the solutions on this page, but they won't work for what I want, since in the first case it suppresses ALL errors, and in the second the text of the error message is passed, but the actual return code is still suppressed (which is what the automation process reads).

Upvotes: 22

Views: 44554

Answers (8)

Andrey Lopatin
Andrey Lopatin

Reputation: 111

Adding 2>nul did the trick. Thanks!

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

This basically suppresses the Error Stream of this command. So even if other errors appeared while doing this operation, they won't appear!

Upvotes: 11

Siya Matsakarn
Siya Matsakarn

Reputation: 427

Try to add after the script

2>Nul 

Example

SET Days=14

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

Hope that helps.

Upvotes: 1

foxidrive
foxidrive

Reputation: 41234

This should solve that issue:

@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"

What it does is provide a file older than 14 days - so it will always be deleted and the 'no files found' message won't appear. I chose the forfiles.exe to copy but you can use any file older than 14 days. All other error messages will appear as normal.

Upvotes: 15

Martin
Martin

Reputation: 1

I had the same problem when trying to delete duplicates in yearly backups on my ext harddisk. None of the solutions found searching the internet (adding @path, leaving out cmd /c in the command parameter) worked for me. System asking 'Are you sure...' brought the follwing solution to my mind: use the /q parameter. The result wipes the 2015 files in my 2016 dir:

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

Upvotes: 0

Sting
Sting

Reputation: 342

Might I add a humble contribution to this already valuable thread. I'm finding that other solutions might get rid of the actual error text but are ignoring the %ERRORLEVEL% which signals a fail in my application. AND I legitimately want %ERRORLEVEL% just as long as it isn't the "No files found" error.

Some Examples:

Debugging and eliminating the error specifically:

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

Using a oneliner to return ERRORLEVEL success or failure:

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

Using a oneliner to keep the ERRORLEVEL at zero for success within the context of a batchfile in the midst of other code (ver > nul resets the 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

For a SQL Server Agent CmdExec job step I landed on the following. I don't know if it's a bug, but the CmdExec within the step only recognizes the first line of code:

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%

Upvotes: 5

Malcolm
Malcolm

Reputation: 576

The solution is to capture the output of the FORFILES command in a FOR loop, search it for strings starting with ERROR, and store the result in a variable. From there, you can use IF/ELSE directives to set the errorlevel accordingly. Here's the code (minus some logging and comments):

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

Just make sure to escape any characters such as >&| in the FOR loop.

Upvotes: 8

Christiaan Westerbeek
Christiaan Westerbeek

Reputation: 11137

This is easily solvable with a one liner. Just append this to your forfiles command:

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

So you'd get:

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."

Only the specified error message is not displayed. All other messages are.

Here's how this works:

  • 2>&1 is used to send STDERR to the same place where we send STDOUT.
  • | find /v /i pipes the output from forfiles to find where /v means NOT containing the specified string and /i means case-insensitive

Upvotes: 4

Nigel
Nigel

Reputation: 1311

To reliably affect the ERRORLEVEL you need to run a subsequent command which is guaranteed to set ERRORLEVEL to 0. I use the command interpreter itself (cmd.exe) to do this as in the following snippet:

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

Hope this helps someone.

Upvotes: 7

Related Questions