Я хочу создать пакетный файл, который запускается из планировщика заданий
Требования:
У меня есть заскриптованные шаги 1
и 2
, (из поиска в сети), но вставка команды файла журнала для меня довольно сложна, так как я не разбираюсь в пакетных сценариях.
Скрипт для шагов 1
и 2
:
forfiles /p "D:\Test" /m *.* /s /d -30 /c "cmd /c move @file E:\Test1"
forfiles /p "E:\Test1" /c "cmd /c del @path"
Может кто-нибудь показать мне, как я могу создавать файлы журналов, используя приведенные выше 2 команды.
В файле журнала должны храниться имена всех файлов, которые были перемещены и удалены, дата и время, а также успех или неудача.
Совершенно бессмысленно сначала перемещать файлы с диска D:
на диск E:
, что требует копирования данных каждого файла, а затем удалять каждый файл на диске E:
. много быстрее удалять файлы старше 29 дней прямо на диске D:
.
Приведенный ниже пакетный файл можно использовать для задачи удаления файла с регистрацией успеха или ошибки каждого удаления файла.
@echo off
if "%~1" == "" goto RunForFiles
del /A /F %1 2>nul
(if not exist %1 (echo %DATE% %TIME% Deleted successfully: %1) else echo %DATE% %TIME% Failed to delete file: %1)>>"E:\LogStoragePath\OldFileDeletionLog.txt"
exit /B
:RunForFiles
md "E:\LogStoragePath" 2>nul
del "E:\LogStoragePath\OldFileDeletionLog.txt" 2>nul
%SystemRoot%\System32\forfiles.exe /P "D:\Test" /M *.* /S /D -30 /C "%SystemRoot%\System32\cmd.exe /D /S /C \"if @isdir == FALSE \"%~f0\" @path\""
Пакетный файл сначала проверяет, вызывается ли он без каких-либо аргументов, что имеет место при запуске пакетного файла запланированной задачей. В этом случае обработка пакетного файла продолжается со строк под меткой RunForFiles
.
Сначала создается каталог (дерево) для файла журнала, не проверяя, можно ли это сделать вообще успешно. Сообщение об ошибке, выводимое командой доктор медицины в уже существующем каталоге файла журнала, подавляется путем перенаправления его с дескриптора STDERR на устройство НУЛ. 2>nul
также подавляет вывод сообщения об ошибке при создании каталога (дерева) по другим причинам, таким как отсутствие разрешений на носитель для этого.
Затем файл журнала, существующий, возможно, из предыдущего выполнения, удаляется с подавлением с помощью 2>nul
сообщения об ошибке, выводимого ДЕЛ, если файл журнала вообще не существует или удаление не может быть выполнено из-за отсутствия разрешений на это (разрешения NTFS, чтение -только атрибут, файл журнала, открытый в данный момент в приложении).
Затем выполняется ФАЙЛЫ для поиска в
D:\Test
указан с опцией пути /P
/S
*.*
(любому), указанному с опцией маски /M
/C
.Команда приводит к запуску еще одного командного процессора Windows с параметрами /D
игнорировать значение реестра AutoRun
и /S
интерпретировать все после следующего параметра /C
как одну строку аргумента с командной строкой для выполнения и параметр /C
для выполнения командной строки, указанной рядом и закрыть себя после завершения выполнения.
Запущенный процесс командного процессора Windows сначала проверяет с помощью сравнения строк с учетом регистра, не является ли текущая запись файловой системы, найденная ФАЙЛЫ с датой последнего изменения старше 29 дней, каталогом. Каталог игнорируется и приводит к немедленному закрытию запущенного cmd.exe
.
Для файла, который выполняется следующим, запущенный cmd.exe
текущий обрабатываемый пакетный файл с полным именем файла, заключенным в "
в качестве аргумента. Таким образом, пакетный файл, обработанный cmd.exe
, запускается forfiles.exe
, который запускает еще один cmd.exe
для обработки того же пакетного файла, но на этот раз с именем файла в качестве аргумента для пакетного файла.
На этот раз обработка пакетного файла продолжается в третьей командной строке, которая использует команду ДЕЛ с параметром /A
(все атрибуты), чтобы отменить неявное значение по умолчанию /A-H
(все атрибуты, кроме скрытого атрибута), чтобы удалить также файл со скрытым набором атрибутов, и параметр /F
, чтобы принудительно удаление файла с установленным атрибутом только для чтения.
Удаление файла в большинстве случаев проходит успешно. Но приложение, в настоящее время открывающее файл старше 29 дней или специальные разрешения NTFS, может привести к сбою удаления файла.
Поэтому условие ЕСЛИ используется для проверки того, действительно ли файл больше не существует, и в этом случае выводится сообщение об успешном выполнении для обработки STDOUT с помощью команды ЭХО с динамическими переменными DATE
и TIME
. В противном случае при неудачном удалении файла выводится ошибочное сообщение с ЭХО с DATE
и TIME
для обработки STDOUT. Выходное сообщение перенаправляется в указанный файл журнала и добавляется к этому файлу журнала, который открывается, изменяется и закрывается для каждого удаляемого файла.
Последнее выполнение пакетного файла для удаления старого файла завершается с помощью команды ВЫХОД с использованием опции /B
, чтобы просто выйти из обработки пакетного файла, а не полностью cmd.exe
обработки этого пакетного файла. cmd.exe
запущенный forfiles.exe
больше нечего делать и закрывается, что приводит к forfiles.exe
поиску следующей записи файловой системы, соответствующей заданным критериям.
Вся задача удаления файла ужасно медленная с использованием этого командного файла. Определенно было бы намного лучше использовать для этой задачи небольшой сценарий PowerShell, обработанный Windows PowerShell, который выполнял бы эту задачу удаления файлов намного быстрее.
Рекомендую также прочитать главу Лучшая и простая концепция удаления резервных копий в моем ответе на Bat-файл для удаления файлов только при наличии более молодых файлов. Как правило, не рекомендуется просто удалять все файлы старше X дней, не проверяя наличие более молодых файлов, особенно если удаляемые файлы являются файлами резервных копий или файлами журналов периодически выполняемой задачи. Решение, опубликованное в указанном ответе, с использованием другой стратегии удаления, отличной от даты последнего изменения, также намного быстрее, чем решение, опубликованное здесь.
Вот также вариант вышеприведенного с первым перемещением каждого старого файла из D:\Test
и его подкаталогов в E:\Test1
без, репликацией дерева каталогов в целевом каталоге с регистрацией успешного или неудачного перемещения файла и, наконец, удалением всех файлов в E:\Test1
записью также успеха или неудачи файла удаление. Ошибка удаления файла очень маловероятна.
@echo off
if "%~1" == "" goto RunForFiles
move /Y %1 "E:\Test1\" >nul 2>nul
(if not exist %1 (echo %DATE% %TIME% Moved successfully: %1) else echo %DATE% %TIME% Failed to move file: %1)>>"E:\LogStoragePath\OldFileMoveLog.txt"
exit /B
:RunForFiles
md "E:\Test1" 2>nul
md "E:\LogStoragePath" 2>nul
del "E:\LogStoragePath\OldFileMoveLog.txt" 2>nul
%SystemRoot%\System32\forfiles.exe /P "D:\Test" /M *.* /S /D -30 /C "%SystemRoot%\System32\cmd.exe /D /S /C \"if @isdir == FALSE \"%~f0\" @path\""
set "ProcessedFile = "
(echo %DATE% %TIME%
for %%I in ("E:\Test1\*") do (
set "ProcessedFile=1"
del /A /F "%%I" 2>nul
if not exist "%%I" (echo Deleted successfully: %%~nxI) else Failed to delete file: %%~nxI
))>"E:\LogStoragePath\OldFileDeletionLog.txt"
if exist "E:\LogStoragePath\OldFileDeletionLog.txt" if not defined ProcessedFile del "E:\LogStoragePath\OldFileDeletionLog.txt"
Последняя командная строка удаляет файл журнала удаления файла при его создании, но содержит только дату и время, потому что ни один файл не был перемещен ранее, и поэтому файл вообще не нужно было удалять.
Для понимания используемых команд и того, как они работают, откройте окно командная строка, выполните в нем следующие команды и очень внимательно прочитайте все страницы справки, отображаемые для каждой команды.
cmd /?
del /?
echo /?
exit /?
for /?
forfiles /?
goto /?
if /?
md /?
move /?
set /?
См. также документацию Microsoft о Использование операторов перенаправления команд.