Подавить 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
Надеюсь, это поможет.