qkowlew: На Зилантконе меня сфоткали мыльницей. Мыльницам не позирую! (фига)
qkowlew ([personal profile] qkowlew) wrote2015-02-14 05:08 pm

CMD скрипт для резервного копирования для Windows XP/Vista/7/8

CMD скрипт для резервного копирования для Windows XP/Vista/7/8
Вниманию желающих виндоузеров, которых НЕ ПУГАЕТ редактирование текстового файла и его запуски из командной строки - представляю написанный мной скрипт.

1 вариант скрипта:
Использует ТОЛЬКО встроенные в Windows от XP до 8 команды системы
Это ровно один файл и более ничего.

В этот файл следует прописать в определённое место параметры:
- какие (доступные на данном компьютере, можно сетевые) каталоги надо бэкапить
- в какие ДВА места (обязательно находящиеся на локальных, не сетевых NTFS дисках) следует делать копию.

Первым запуском скрипт создаёт ежедневное задание, в котором запускается он сам.
Главный набор особенностей, отличающий его от многих других решений:

- ежедневно создаётся свежая копия в подпапке latest
- предыдущие состояния "копируются" в подпапки с именами вида YYMMDD-HHMMSS (дата и время старта скрипта), то есть можно посмотреть БЫСТРО и ПРОСТО слепок каталога на эти моменты времени, НЕ используя никаких программ, кроме обычного файлового менеджера.
- Все файлы в этих папках являются хард линками, а это означает, вся эта последовательность бэкапов занимает места (сумму размеров всех исходных файлов ПЛЮС сумму объёмов их версий).
- Если ни один файл не изменился НИ размером, НИ таймстампом - новый бекап НЕ делается.
- Файл считается изменившимся, если у него изменился ИЛИ таймстамп (В ЛЮБУЮ сторону - это защита от кривостей таймзон!!!!), ИЛИ размер.

Минус - встроенная в Windows команда FSUTIL не умеет делать хард линки на сетевых дисках. Поэтому если вам всё-таки нужно делать копию на сетевой диск - CMD скрипт для резервного копирования для Windows XP/Vista/7/8 в том числе на сетевые диски с помощью бесплатной программы KillCopy, сайт автора.

Бета-тестеры (обоих вариантов) приветствуются.

UPD1: файлов лежащих глубже чем позволяет длина передаваемого в ком строке пути - скрипт не видит!
UPD2: так как консоль Windows - не UTF, проблема с националными символами, отличными от текущей cp для консоли - неустранимы.
UPD3: по багрепорту исправил обработку времени
UPD4: добавление назначенного задания в написанном как сейчас (в 1.0-1.1 версиях) виде работает в Windows 7 и НЕ работает корректно в Windows XP SP2 - в XP SP2 Schtasks /QUERY оказывается не позволяет посмотреть параметры конкретного задания. в SP3 - в одних версиях позволяет в других нет. Похоже, зависит от языка системы. 8-О
Schtasks /Query /TN "%MyName%" >nul 2>&1
if errorlevel 1 Schtasks /Create /SC DAILY /TN "%MyName%" /TR "'%ComSpec%' /c '%MyFullPath%'" >nul 2>&1

Под XP правильная команда должна обязательно содержать параметры запуска задания - система (сетевое имя компьютера, даже если это локальный комп), пользователь, пароль (пустой не стоит) или /RU SYSTEM:
Schtasks /Create /SC DAILY /TN "%MyName%" /TR "'%ComSpec%' /c '%MyFullPath%'" /S \\MYMACHINE /U userbackup /P lkjlihkuihkuh

UPD5: Если в пути встречается амперсэнд - получается полная фигня, команда очередная делится на части... В результате v1.3 переписана так, что сначала записывает список ВСЕХ файлов по подкаталогам в файл в %TEMP% а потом засасывает файл снова и уже по извлекаемым из него строкам анализирует... За 9 минут обошёл каталог РАБОТА нашёл в нём 106735 файлов и сформировал полный файллист размером 11 мегабайт. Сейчас проверяет наличие, размер и таймстамп файлов в ещё не существующем бекапе этой папки и формирует список файлов на копирование. За 1 час проверил 44000 файлов... А там ещё эти 75 гигабайт копировать, хехе...

Интересно, что xcopy /Y /S /T /E %SOURCE% %PATH1%\%DEST1%\%2\ на этой структуре обломалось в самом начале и не создало большей части каталогов.

Интересно, что FAR по Alt-F7 (и, соответственно, при ручном копировании) Found files: 107392, folders: 11752 на этом же каталоге.

UPD6: А. таки FOR /R не находит 652 спрятанных и 5 системных файлов. ;-) Отсюда разница с ФАРом.

UPD7: Выложил 1.3 версию исправленную. Различает Windows 7 и Windows XP при создании ежедневного задания. Обходит дерево со спецсимволами корректно.

UPD8: О скорости работы. Сеть 100 Мбит, винты сата2. 75 гигабайт суммарный объём, 106735 файлов в 11752 каталогах. Стартовый обход дерева - 9 минут, обход со сравнением размера-таймстампа - 2.5 часа, копирование 38 гигабайт - 3.5 часа, то есть 75 гиг скопируется за 7 часов. Это _первая_ копия, полная. Ессно, все "дифференциальные" будут быстрее на процесс копирования.

Спасибо darkwing - на миллионе файлов получается, что памяти сжирает cmd.exe аж под 4 гига в пике, тратит 30 минут на 1 проход, около 10 часов - на CheckUpdate...

Так что сделать более быструю проверку актуально. А то 10-30 файлов в секунду - это печаль-печаль.

UPD9: Перенёс строку set MyName=%0 перед CALL :SetUpTask по вот этому багрепорту

[identity profile] darkwinq.livejournal.com 2015-02-14 02:34 pm (UTC)(link)
Отлично.

[identity profile] qkowlew.livejournal.com 2015-02-17 05:08 am (UTC)(link)
Выложил версию 1.3 - советую пробовать именно её. И см. апдейт.

[identity profile] besm6.livejournal.com 2015-02-14 09:25 pm (UTC)(link)
Когда я читаю то, что пишут люди, разбирающиеся в виндах, я каждый раз радуюсь, что в свое время за основную рабочую систему (включая интерактивную часть) взял линукс...

[identity profile] qkowlew.livejournal.com 2015-02-15 12:26 pm (UTC)(link)
Я и там и там пишу всякое...
И везде свои проблемы и ограничения.

[identity profile] aywen.livejournal.com 2015-02-14 09:28 pm (UTC)(link)
О! Это хорошо.

[identity profile] vgiv.livejournal.com 2015-02-15 02:50 am (UTC)(link)
Не будет работать между полуночью и 10 часами утра:)

В начале нужно как-то так:

set HR=%TIME:~0,2%
if "%HR:~0,1%" equ " " set HR=0%HR:~1,1%
set DATE1=%DATE:~8,2%%DATE:~3,2%%DATE:~0,2%-%HR%%TIME:~3,2%%TIME:~6,2%


P.S. То есть будет, но не при всяких региональных настройках.
Edited 2015-02-15 02:52 (UTC)

[identity profile] qkowlew.livejournal.com 2015-02-16 11:24 am (UTC)(link)
Спасибо дельное исправление.

[identity profile] aywen.livejournal.com 2015-02-16 04:26 am (UTC)(link)
Правильно ли я понимаю, что путь к каталогам, откуда бэкапить, начинается с CALL :Backup1Dir ?
И таких строчек может быть несколько?

[identity profile] qkowlew.livejournal.com 2015-02-16 11:13 am (UTC)(link)
Да, несколько.
И каталог U:\USERS\q например надо записывать как:
CALL :Backup1Dir U:\USERS q

то есть - вместо последнего разделительного бэкслеша пробел.
И в U:\USERS и q не должно быть пробелов.

Иначе важная часть обработки пути конкретного файла (выделение RELPATH) работать корректно не будет. :(

Пути внутри бекапаемых каталогов могут содержать пробелы - это скрипт отработает корректно.

Возможно, есть символы, наличие которых в путях к файлам и именах файлов приведёт к непопаданию соответствующей ветки в бекап - мне не хватило терпения сделать подробный тест на эту тему.

[identity profile] qkowlew.livejournal.com 2015-02-17 04:55 am (UTC)(link)
Так. Выложил версию 1.3 - советую пробовать именно её.

[identity profile] darkwinq.livejournal.com 2015-02-17 12:50 pm (UTC)(link)
В начало скрипта имеет смысл вписать:

chcp 866

Тогда скрипт не будет зависеть от кодировки консоли по умолчанию

[identity profile] rrumil.livejournal.com 2015-02-19 07:12 am (UTC)(link)
Я для тех же целей пользуюсь nnbackup, он весьма шустр

[identity profile] wladimir-m.livejournal.com 2015-03-13 07:25 am (UTC)(link)
Сергей, спасибо за скрипт - весьма полезная штука. Но процедуре SetUpTask меня смутила команда
set MyName=%0
Какое значение тут должно получить MyName? Имя файла со скриптом? Но, так как процедура вызывается через Call :SetUpTask, %0 получает значение :SetUpTask, со всеми вытекающими последствиями.
Проверял под XP, 2003, Win7: файлик tst.cmd с содержимым
call :LittleEcho
goto Exit
:LittleEcho
echo %0
всегда выдаёт ":LittleEcho", а не "c:\tst.cmd"

[identity profile] qkowlew.livejournal.com 2015-03-13 12:43 pm (UTC)(link)
Да, неправ.
Перенёс строку set MyName=%0
перед CALL :SetUpTask
Edited 2015-03-13 12:48 (UTC)

точно hardlink? не Junction?

[identity profile] urban-hero-ru.livejournal.com 2015-11-28 08:34 pm (UTC)(link)
я бы килкопи поменял на фасткопи,
а хардлинки - на джанкшены

choco install linkshellextension fastcopy -y