PDA

Показать полную графическую версию : [решено] Bat ограничивающий кол-во хранимых каталогов.


Bullet-Avalon
14-09-2010, 13:32
Добрый день, итак расскажу по подробнее, что именно хочу сделать и , что не получается.

Данный скрипт, выполняется каждый день и должен
1. На win2008 делать SystemStateBackup на локальный диск (D)
2. Проверять кол-во бэкапов в указанной папке, на локальном компе (не более 1-го). Путь выглядит так - D:\WindowsImageBackup\server\SystemStateBackup в которой находятся папки с датой, которая соответствует дате бэкапа. Если там находится более 1 бэкапа, то удалить старые бэкапы(папки и их содержимое), оставив тока самый свежий.
3. Проверить папку для бэкапов на удаленной шаре, ограничение на кол-во бэкапов не более 5, опять таки если более -удалить наиболее старые.
4.Копировать с локального хранилища бэкап (пункт2) на удаленную шару(пункт3)

Проблема в следующем, когда скрипт находит что папок больше указанного кол-ва, он пытается их удалить, НО выводит потом сообщение - "ПАПКА НЕ ПУСТА", тоесть для теста создал неск пустых папок, он их удалил норм, а если там уже чтото содержится то выводит данное сообщение. Прошу вас помочь найти и исправить ошибку.

Итак вот сам код

@echo off
::Первая часть скрипта - SystemStateBackup
rem run the backup echo Backing up systemstate to Local Disk D
wbadmin start systemstatebackup -backuptarget:d: -quiet



::Вторая часть скрипта - Проверка кол-ва бэкапов на локальном диске
@Echo Off
SetLocal EnableDelayedExpansion
:: Папка с бэкапами, макс кол-во бэкапов
Set $DST=D:\WindowsImageBackup\server\SystemStateBackup
Set $OLD=1
:: Находим текущие день/месяц/год
For /F "Tokens=1 Delims=." %%i In ('WMIC OS Get LocalDateTime^|Find "."')
Do Set $Time=%%i
Set $Y=%$Time:~0,4%&Set $M=0%$Time:~4,2%&Set $D=0%$Time:~6,2%
Set $M=%$M:~-2%&Set $D=%$D:~-2%
:: Ограничиваем количество архивов
For /F "Tokens=1-3 Delims=." %%i In ('DIR /B/A:D %$DST%\??.??.????')
Do Set $_%%k%%j%%i=%%i.%%j.%%k
For /F "Tokens=2 Delims==" %%i In ('Set $_^|Sort /R') Do (
Set /A $OLD-=1
If !$OLD! LSS 0 RD /S/Q "%$DST%\%%i"
)


::Третья часть скрипта - Проверка кол-ва бэкапов на удаленной шаре
@Echo Off
SetLocal EnableDelayedExpansion
:: Папка с бэкапами, макс кол-во бэкапов
Set $DST=\\192.168.0.5\backup$\SystemStateDc
Set $OLD=4
:: Находим текущие день/месяц/год
For /F "Tokens=1 Delims=." %%i In ('WMIC OS Get LocalDateTime^|Find "."')
Do Set $Time=%%i
Set $Y=%$Time:~0,4%&Set $M=0%$Time:~4,2%&Set $D=0%$Time:~6,2%
Set $M=%$M:~-2%&Set $D=%$D:~-2%
:: Ограничиваем количество архивов
For /F "Tokens=1-3 Delims=." %%i In ('DIR /B/A:D %$DST%\??.??.????')
Do Set $_%%k%%j%%i=%%i.%%j.%%k
For /F "Tokens=2 Delims==" %%i In ('Set $_^|Sort /R') Do (
Set /A $OLD-=1
If !$OLD! LSS 0 RD /S/Q "%$DST%\%%i"
)


:: Четвертая часть скрипта - копирование с локальной папки на удаленную шару
Set InDir="D:\WindowsImageBackup\server\SystemStateBackup "
Set Double1="\\192.168.0.5\backup$\SystemStateDc"
rem Set DT=%Date%
Set DT=%Date:~6,4%%Date:~3,2%%Date:~0,2%
Call :CopyDir %InDir% %Double1%
GoTo End
:CopyDir
Set Otkuda="%~1\*.*"
Set Kuda1=%~1
Set Kuda1="%~2\%DT%_%Kuda1:~3,1000%\"
xcopy %Otkuda% %Kuda1% /Y /S
:End

amel27
15-09-2010, 04:18
Проблема в следующем, когда скрипт находит что папок больше указанного кол-ва, он пытается их удалить, НО выводит потом сообщение - "ПАПКА НЕ ПУСТА", тоесть для теста создал неск пустых папок, он их удалил норм, а если там уже чтото содержится то выводит данное сообщение. »не похоже чтобы скрипт, поищите (http://forum.oszone.net/search.php) по форуму по фразе "папка не пуста", например:
Ошибка - [решено] Не удается удалить [название папки]. Папка не пуста. (http://forum.oszone.net/thread-97474.html)

megaloman
15-09-2010, 19:15
Как-то сложновато у Вас ... Вроде бы для разных папок делается одно и то же действие, а Вы зачем-то пишите два куска для этого. Вот батник, который заменяет Ваши вторую и третью части скрипта: работает одна и та же подпрограмма LimCountDir. В ней сначала подсчитываем число папок, затем сколько папок надо удалить, затем по порядочку удаляем их, начиная с самых старых.
Процедура в указанной папке (Where) оставляет указанное кол-во самых свежих подпапок (HowMuch).
для сортировки по датам используется ключ /O команды Dir
С Вашим копированием не разбирался, если бы Вы просто описали, по какому принципу образуются имена файлов (директорий) - было бы проще.@Echo off
rem Пути указываем без кавычек и без \ и пробелов на конце
rem -------------------------------------------

Set HowMuch=1
Set Where=F:\Delete\Install
rem ---------------------------------------------------
Call :LimCountDir "%Where%" %HowMuch%
rem ---------------------------------------------------

Set HowMuch=5
Set Where=\\SERVER_NT\{Общая}\Delete\Install
rem ---------------------------------------------------
Call :LimCountDir "%Where%" %HowMuch%
rem ---------------------------------------------------
GoTo :Eof

rem ----------------------------------------------------
:LimCountDir

rem Подсчитаем кол-во директорий (Count) в указанной папке %1 (Путь передали в аргументе)
Set Count=0
FOR /F "usebackq delims=" %%i IN (`Dir /B /A:D /O:D "%~1\"`) DO Call :CountDir

rem Удалим старые директории в указанной папке %1 сверх максимального количества %2 (передали в аргументе)
Set /A DelCount=%Count%-%2
Set Count=0
FOR /F "usebackq delims=" %%i IN (`Dir /B /A:D /O:D "%~1\"`) DO Call :DelNumCount %DelCount% "%~1\%%i"
GoTo :Eof

:CountDir
Set /A Count=%Count%+1
GoTo :Eof

:DelNumCount
Set /A Count=%Count%+1
If %Count% LEQ %1 Rd %2 /S /Q
GoTo :Eof
rem ----------------------------------------------------

kiripanda
16-09-2010, 00:30
сначала подсчитываем число папок, затем сколько папок надо удалить... »
а на пуркуа считать?
FOR /F "usebackq skip=%2 delims=" %%i IN (`Dir /B /A:D /O:-D "%~1\"`) DO RD /S/Q "%~1\%%i"
skip=%2 — сколько папок оставить

megaloman
16-09-2010, 10:00
FOR /F "usebackq skip=%2 delims=" %%i IN (`Dir /B /A:D /O:D "%~1\"`) DO RD /S/Q "%~1\%%i" Так Вы оставите самые старые папки. Спасибо, заставили внимательнее прочесть хелп Dir /O Сортировка списка отображаемых файлов.
D По дате (сперва более старые)
Префикс "-" обращает порядок
Мой код упростится вообще до минимума
@Echo off
rem Пути указываем без кавычек и без \ на конце
rem -------------------------------------------

Set HowMuch=1
Set Where=F:\Delete\Install
Call :LimCountDir "%Where%" %HowMuch%

Set HowMuch=5
Set Where=\\SERVER_NT\{Общая}\Delete\Install
Call :LimCountDir "%Where%" %HowMuch%

GoTo :Eof

:LimCountDir
FOR /F "usebackq skip=%2 delims=" %%i IN (`Dir /B /A:D /O:-D "%~1\"`) DO Rd "%~1\%%i" /S /Q
GoTo :Eof

Bullet-Avalon
16-09-2010, 10:11
Спасибо Вам большое, опробовал ваш скрипт megaloman, все отлично работает!
Благодарю всех.

kiripanda
16-09-2010, 17:49
Так Вы оставите самые старые папки.»Упс. Не посмотрел на порядок сортировки, ибо не тестировал. Действительно, нужен"Префикс "-" обращает порядок"
Мой код упростится вообще до минимума »Можно обойтись без Set

@Echo off
rem Пути указываем без \ на конце
rem -----------------------------

Call :LimCountDir "F:\Delete\Install" 1

Call :LimCountDir "\\SERVER_NT\{Общая}\Delete\Install" 5

GoTo :Eof

:LimCountDir
FOR /F "usebackq skip=%2 delims=" %%i IN (`Dir /B /A:D /O:-D "%~1\"`) DO Rd "%~1\%%i" /S /Q
GoTo :Eof

megaloman
16-09-2010, 19:19
kiripanda,Очевидно Можно обойтись без Set Однако я придерживаюсь обычно такого стиля: в начале я определяю некие исходные параметры задачи, что требует ряд Set, а затем уже рисую сам батник. Надо было бы написать:Echo off
rem Пути указываем без кавычек и без \ на конце
rem -------------------------------------------

Set HowMuch1=1
Set Where1=F:\Delete\Install

Set HowMuch2=5
Set Where2=\\SERVER_NT\{Общая}\Delete\Install

Call :LimCountDir "%Where1%" %HowMuch1%
Call :LimCountDir "%Where2%" %HowMuch2%

GoTo :Eof

:LimCountDir
FOR /F "usebackq skip=%2 delims=" %%i IN (`Dir /B /A:D /O:-D "%~1\"`) DO Rd "%~1\%%i" /S /Q
GoTo :Eof Обычно я еще и комментарии пишу к исходным данным. Делаю это для того, чтобы максимально надёжно и быстро перенастроить батник, если условия поменялись. В принципе, для уменьшения числа строк кода, можно обойтись и без Call. В угоду краткости я не иду на ухудшение в удобстве использования. Однако, в примере я отошел от этого правила, так как смысл имела только процедура, а всё остальное - тестовые строки.




© OSzone.net 2001-2012