Подавить FORFILES "no files found" error

Я работаю с пакетным файлом для удаления архивных документов старше 14 дней, и я вызываю файл из процесса автоматизации (Lansa Composer), который читает код возврата script, чтобы увидеть, есть ли проблема. Здесь 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"

Проблема заключается в том, что script возвращает код ошибки и печатает "ERROR: файлы не найдены с указанными критериями поиска", если он не находит файлы для удаления, когда я действительно хочу, чтобы он возвращал ошибку если есть проблема с доступом к каталогу или запуском команды del и т.д. Есть ли способ получить этот script для подавления ошибки "без файлов", но разрешить другим проходить через?

После некоторого Googling я попробовал решения на этой странице, но они не будут работать для того, что я хочу, так как в первом случае это подавляет ВСЕ ошибки, а во втором передается текст сообщения об ошибке, но фактический код возврата все еще подавляется (что и читает процесс автоматизации).

Ответ 1

Решением является захват вывода команды FORFILES в цикле FOR, поиск его для строк, начинающихся с ERROR, и сохранение результата в переменной. Оттуда вы можете использовать директивы IF/ELSE для установки errorlevel соответственно. Здесь код (минус некоторые записи и комментарии):

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.

Ответ 2

Это должно решить эту проблему:

@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 дней. Все остальные сообщения об ошибках будут отображаться как обычно.

Ответ 3

Добавление 2> NUL сделал свое дело. Спасибо!

forfiles/pd:\todayfiles/d +0/c "cmd/c echo @path" 2> nul | найти ":"/c

Это в основном подавляет поток ошибок этой команды. Таким образом, даже если при выполнении этой операции возникли другие ошибки, они не появятся!

Ответ 4

Могу ли я добавить скромный вклад в этот уже ценный поток. Я обнаружил, что другие решения могут избавиться от фактического текста ошибки, но игнорируют% 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 Agent CmdExec я приземлился на следующее. Я не знаю, если это ошибка, но 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%

Ответ 5

Чтобы надежно повлиять на ERRORLEVEL, вам нужно запустить следующую команду, которая гарантированно установит ERRORLEVEL в 0. Я сам использую сам интерпретатор команд (cmd.exe), как в следующем фрагменте:

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

Надеюсь, это поможет кому-то.

Ответ 6

Это легко разрешимо с помощью одного вкладыша. Просто добавьте это в команду 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 pipe вывод из forfiles to find где /v означает NOT, содержащий указанную строку, а /i означает нечувствительность к регистру

Ответ 7

У меня была такая же проблема при попытке удалить дубликаты в ежегодных резервных копиях на моем внешнем жестком диске. Ни одно из найденных решений поиска в интернете (добавление @path, @path cmd/c в параметре команды) мне не @path. Системный вопрос "Вы уверены..." напомнил мне следующее решение: используйте параметр /q. Результат стирает файлы 2015 года в моем каталоге 2016 года:

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

Ответ 8

Попробуй добавить после скрипта

2>Nul 

пример

SET Days=14

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

Надеюсь, это поможет.