Здесь мы рассмотрим, как сделать систему дифференциального бэкапа «из коробки» (ну почти), с привлечением минимального количества внешних модулей, в лучших традициях UNIX-way.
Будем использовать 7za.exe \ 7z, а также UNIX-like утилиту pdate.exe, чтобы со временем нам было работать также удобно, как и в ламповом *NIX, а заменой bash нам будет «простонародный» BAT. Предыстория и подробности — под катом.

Предыстория


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

Взглянув на сие зашифрованное непотребство, я с благодарностью вспомнил про то, что каждый день у меня делается бэкап этой (и не только этой) шары встроенными средствами Windows Server 2003 SP2 x64. Но, полистав этот бэкап, я понял, что в плане резервного копирования средствами самой Windows не все так радужно. Во-первых, полный бэкап оказался недоступен, а значит восстановить cold-data (файлы, которые меняются очень редко) вряд ли получится. Во-вторых, восстановление из созданного инкрементального бэкапа оказалось задачей нетривиальной — за каждый шаг получалось восстановить только данные, которые были изменены, и ничего более. Получается, чтобы восстановить хотя бы все измененные данные (раз полный бэкап оказался утерян), то пришлось бы перебирать по очереди все бэкапы — не совсем то, что я ожидал от инкрементального бэкапа в таком случае.

Кто то из вас может сказать — надо было проверять работоспособность бэкапа, и да, так оно и есть. Но тот из вас, кто работает в торговле, может понять, куда может уходить время админа — да-да, они самые, онлайн-кассы.

Крепко задумавшись, я вспомнил свое первое знакомство с системой инкрементального копирования fsbackup за авторством Максима Чиркова www.opennet.ru/dev/fsbackup — гибкость, простота, в то же время обилие возможностей и открытый формат хранения архивов (tar). Жаль, что система разработана под *NIX / Linux. Google также не ответил на мой вопрос про подобную систему под Windows. Самое полезное, что я нашел — это краткий гайд хабровчанина antip0d и пример скрипта для резервного копирования. Именно материал по последней ссылке я и использовал для своего скрипта.

Собираем систему


В первую очередь, скачиваем последнюю стабильную версию. На момент написания это 16.04. Наш бэкап будем хранить в 7z архиве: поддержка многопоточности, шифрованных/многотомных архивов, а скорость извлечения из 7z выше скорости упаковки в 10-20 раз!
UPD: Спасибо хаброжителю Taciturn за поправку — вы также можете использовать 7z.exe, уже установленный в вашей системе. Функциональных различий между 7z и 7za я не выявил.

Нас интересуют:
7za.exe — автономная версия 7-Zip.
7za.dll — библиотека для работы с архивами 7z
7zxa.dll — библиотека для распаковки 7z архивов.
Для 64-битных ОС используем те же файлы из каталога x64.
К сожалению, ссылка из используемого мной материала на утилиту pdate никуда не ведет, единственная найденная мной версия
pdate v1.1 build 2007.12.06
© 2005-2007 Pavel Malakhov 24pm@mail.ru
Ссылка из встроенного мануала pdate ведет туда же, а именно — в никуда.
pm4u.opennet.ru/mysoft/pdate.htm
К счастью, на том же ресурсе есть краткая статья по этой программе, там же ее можно скачать.

Мной была использована следующая структура каталогов:
D:\winfsbackup — корневая директория скрипта и связанных файлов
D:\winfsbackup\7z — библиотеки и исполняемый файл 7za
D:\winfsbackup\backup — место хранения бэкапов (можно переназначить путем правки переменных, как и любые другие используемые файлы)
D:\winfsbackup\lists — списки включаемых и исключаемых файлов. О них расскажу чуть позже
D:\winfsbackup\log — логи
D:\winfsbackup\pdate
D:\winfsbackup\tmp — устанавливает рабочий каталог для временного базового архива
D:\winfsbackup\winfsbackup.bat — сам скрипт.

Логика работы


После обработки переменных скрипт смотрит блок :Main, где указывается логика работы бэкапа — в каком случае должен выполниться новый бэкап, а в каком случае — обновить существующий базовый архив. По умолчанию, новый архив создается в начале месяца, а все файлы из директории backup перемещаются в \backup\old, или если базового архива не существует.
Уже во время написания статьи я понял, что нужно добавить возможность обновления базового архива — упрощенный вариант «полный бэкап раз месяц + дифференциальный бэкапы к нему» целесообразно использовать для файловых обменников размером до ~250 Гб. Для моего файлообменника в 550 Гб с преобладанием мелких файлов скорость бэкапа оказалась неудовлетворительна (почти 55 часов). Справедливости ради стоит сказать, что это не может служить сколь нибудь достоверным замером производительности — в процессе бэкапа выяснилось, что некоторые файлы недоступны (привет chkdsk), а бэкап складывался в раздел удаленного сервера, который тоже был занят операциями дискового ввода-вывода.

:Main
REM Здесь описаны условия, в каком случае будет выполняться полный \ дифференциальный бэкап, либо обновление базового бэкапа.

REM Базовое условие - создание полного бэкапа если он не существует
IF NOT EXIST %baseArch% GOTO BaseArchive

REM полный бэкап раз месяц + дифференциальныt бэкапы к нему
IF %dm% EQU 1 GOTO BaseArchive ELSE GOTO UpdateArchive

REM обновляем базовый архив в 1 день месяца
REM IF %dm% EQU 1 GOTO UpdateBase ELSE GOTO UpdateArchive

REM Ежеквартальный полный бэкап (2, 19, 36 неделя года)
REM IF NOT %wn%.%dw% EQU 02.5 GOTO UpdateArchive
REM IF NOT %wn%.%dw% EQU 19.5 GOTO UpdateArchive
REM IF NOT %wn%.%dw% EQU 36.5 GOTO UpdateArchive

REM Обновляем базовый архив, каждую субботу
REM IF %dw% EQU 6 (GOTO UpdateBase) ELSE (GOTO UpdateArchive)

REM А здесь можно разместить действие, которое выполнится если предыдущие условия не отработают.
REM Я стараюсь избегать подобного поведения
ECHO Warning! No one condition matching, check :Main block of script >> %Log%
GOTO End

Первые 2 условия включены по-умолчанию, и описывают полный бэкап раз месяц + дифференциальные бэкапы. Остальные условия альтернативны, то есть при включении одного нужно выключить другое, или изменить логику работы на свой вкус.

Переменные


dm, dw, wn — соответственно день месяца, день недели и номер недели (в численном выражении).
verboseLevel — режим «говорливости», выдает информацию о том, куда будет записываться архив, и прочее. Полезно, когда вносишь в структуру скрипта серьезные изменения.
tmpDir — место сохранения временного файла. По умолчанию, 7-Zip строит новый базовый файл архива в том же самом каталоге, где и старый базовый файл архива. Определяя этот ключ, вы можете установить рабочий каталог, где будет построен временный базовый файл архива. После того, как временный базовый файл архива построен, он копируется поверх первоначального; затем временный файл удаляется.

Дифференциальный бэкап


По умолчанию, в дифференциальный бэкап помещаются файлы, которых нет в базовом архиве, а также более новые файлы. При желании, это поведение можно изменить. Описания ключей есть в стандартном файле справки 7z.

У такого подхода есть свои плюсы (которые я уже успел оценить) — быстрота разворачивания из бэкапа. В случае полного восстановления разворачиваем последний (или любой другой) имеющийся дифференциальный бэкап, а затем — полный архив, отказываясь от перезаписи имеющихся файлов.

Некоторые опции командной строки


-bsp2 — выводит строку с прогрессом выполнения в STDERR. STDOUT 7z перенаправлен в лог, прогресс, естественно, туда не пишется. Эта команда выводит его в STDERR, для большей информативности.

-ssw — упаковывает файлы, открытые для записи другим приложением. Если этот ключ не установлен, 7-Zip не включает такие файлы в архив.

-slp — крайне полезная опция. Режим больших страниц увеличивает скорость сжатия. Однако, есть пауза в начале сжатия, в то время когда 7-Zip распределяет большие страницы в памяти. Если 7-Zip не может разместить большие страницы, он размещает обычные маленькие страницы. Кроме того, Диспетчер задач не показывает реальное использование памяти программами, если 7-Zip использует большие страницы. Эта особенность работает только на Windows 2003 / XP x64. Также нужно иметь права администратора для вашей системы. Рекомендованный размер оперативной памяти для этой особенности — 3 Гб или больше. если вы используете режим -slp, ваша система Windows может зависнуть на несколько секунд, когда 7-Zip выделяет блоки памяти. Когда Windows пытается выделить большие страницы из оперативной памяти для 7-Zip, Windows может подвесить другие задачи на это время. Это может выглядеть как полное зависание системы, но затем ее работа восстанавливается, и, если распределение прошло успешно, 7-Zip работает быстрее. Не используйте режим -slp, если вы не хотите, чтобы другие задачи быть «подвешены». Кроме того, бессмысленно использовать режим -slp для сжатия небольших наборов данных (менее 100 МБ). Но если вы сжимаете большие наборы данных (300 Мб или более) методом LZMA с большим словарем, вы можете получить увеличение скорости на 5% -10% в режиме -slp.
-mmt=on — устанавливает режим многопоточности. Если у вас многопроцессорная / многоядерная система, вы можете получить увеличение скорости с этим ключом. 7-Zip поддерживает режим многопоточности только для сжатия LZMA/LZMA2 и сжатия/распаковки BZip2.

-ms=off — отключает создание solid-архивов. Качество сжатия при этом, конечно же, падает, однако есть весьма весомые плюсы — вы можете периодически обновлять данные базового архива чтобы уменьшить размер дифференциальный бэкапов, и так как архив не является целостным, не нужно будет его дополнительно «пережимать». Non-solid архив более стоек к повреждениям, и время извлечения из него происходит заметно быстрее.

Include / exclude листы
По умолчанию определено 2 типа списка — список включаемых файлов / директорий (include_general.txt), и 2 списка исключений (exclude_general.txt, exclude_regexp.txt).

Список включения также поддерживает UNC-пути. Для того, чтобы поместить файл / директорию в исключения, путь должен быть относительным.

Например, если директория для бэкапа E:\foo\bar, и мы хотим исключить вложенную директорию E:\foo\bar\somefolder, то в exclude_general.txt мы должны добавить bar\somefolder или bar\somefolder\

Путь без слэша в конце может относиться как к файлу, так и к директории.
В exclude_regexp.txt вносятся исключаемые по regexp файлы, которые просматриваются рекурсивно. * — последовательность произвольных символов,? — любой символ.
7-Zip не использует системный синтаксический анализатор подстановочных знаков, поэтому «любой файл» для 7 Zip это '*', а '*.*' — файл, имеющий расширение.

Ну и наконец, скрипт целиком:

@ ECHO OFF
REM Sources were found on http://sysadminwiki.ru/wiki/Резервное_копирование_в_Windows
CD %~dp0
TITLE winfsbackup
MODE CON: COLS=120 LINES=55
ECHO Setting vars...
REM --- Definition block ---
SET verboseLevel=1
SET tmpDir=D:\winfsbackup\tmp
SET run_7z=D:\winfsbackup\7z\7za.exe
SET run_pdate=D:\winfsbackup\pdate\pdate.exe
FOR /F "usebackq" %%a IN (`%run_pdate% e`) DO (SET dm=%%a)
FOR /F "usebackq" %%a IN (`%run_pdate% u`) DO (SET dw=%%a)
FOR /F "usebackq" %%a IN (`%run_pdate% V`) DO (SET wn=%%a)
SET LogDir=D:\winfsbackup\log
SET Log=%LogDir%\general.log
SET dDir=D:\winfsbackup\backup
SET dlmDir=D:\winfsbackup\backup\old
SET baseArch=%dDir%\general.7z
SET IncludeList=lists\include_general.txt
SET ExcludeList=lists\exclude_general.txt
SET ExcludeRegexp=lists\exclude_regexp.txt
SET updArch_dw=%dDir%\day_general_%dw%.7z
SET updArch_wn=%dDir%\week_general_%wn%.7z

IF %verboseLevel%==0 GOTO Main
ECHO Verbose mode ON!
ECHO Today is %wn% week of year, %dw% day of week.
ECHO Full quarter backup will execute (if enabled) on 2, 19 and 36 week, friday.
ECHO Temporary directory is %tmpDir%
ECHO Now logging into %Log%
ECHO Current backup directory is %dDir%, older backups stored into %dlmDir%

:Main
REM Here discribed conditions - in which case script will make new backup, update older one, etc
REM You are free to change these conditions
REM Make sure you envisaged all possible cases
REM Actions here are not disigned to be active more than 1 at same time, excluding base condition
REM If you want multiple conditions, you should edit it

REM Base condition - full backup will be created if it is not exist
IF NOT EXIST %baseArch% GOTO BaseArchive

REM Command below turns on making full backup at 1'st day of every month, in other days - increments
REM IF %dm% EQU 1 GOTO BaseArchive ELSE GOTO UpdateArchive

REM This option enables updating full backup every month
IF %dm% EQU 1 GOTO UpdateBase ELSE GOTO UpdateArchive

REM Uncomment these 3 commands if you want to run full backup ~every quarter (2, 19, 36 week of year)
REM IF NOT %wn%.%dw% EQU 02.5 GOTO UpdateArchive
REM IF NOT %wn%.%dw% EQU 19.5 GOTO UpdateArchive
REM IF NOT %wn%.%dw% EQU 36.5 GOTO UpdateArchive

REM This option enables rewriting base archive every saturday with new files in order to decrease size of increments
REM IF %dw% EQU 6 (GOTO UpdateBase) ELSE (GOTO UpdateArchive)

REM Here you can place default action if conditions of previous ones were not executed.
%run_pdate% "Z --- \A\c\t\i\o\n \w\a\s\ \n\o\t \s\e\l\e\c\t\e\d\! >> %Log%
ECHO Warning! No one condition matching, check :Main block of script
GOTO End

:BaseArchive
ECHO Clear %dlmDir% and move data of previous month to that dir...
IF NOT EXIST %dlmDir%\nul MKDIR %dlmDir%
DEL /Q %dlmDir%\*
MOVE /Y %dDir%\* %dlmDir% 2> nul

%run_pdate% "====== Y B =======" > %Log%
%run_pdate% "Z --- \S\t\a\r\t \t\o \c\r\e\a\t\e \n\e\w \a\r\c\h\i\v\e" >> %Log%

ECHO Creating new backup %baseArch%
%run_7z% a %baseArch% -w%tmpDir% -i@%IncludeList% -x@%ExcludeList% -xr@%ExcludeRegexp% -bsp2 -ssw -slp -scsWIN -mmt=on -mx3 -ms=off >> %Log%
IF %ERRORLEVEL%==0 (
	%run_pdate% "Z --- \E\x\i\t \c\o\d\e \0 \- \a\r\c\h\i\v\e \s\u\c\c\e\s\s\f\u\l\l\y \c\r\e\a\t\e\d!" >> %Log%
	) ELSE (
		IF %ERRORLEVEL%==1 (
		%run_pdate% "Z --- \W\a\r\n\i\n\g\! \R\e\c\i\e\v\e\d\ \e\x\i\t \c\o\d\e \1" >> %Log%
			) ELSE (
				IF %ERRORLEVEL%==2 (
				%run_pdate% "Z --- \E\x\i\t \c\o\d\e \2 \- \F\A\T\A\L \E\R\R\O\R\!" >> %Log%
				) ELSE (
					IF %ERRORLEVEL%==7 (
					%run_pdate% "Z --- \E\x\i\t \c\o\d\e \7 \- \C\o\m\m\a\n\d \p\r\o\m\p\t \e\r\r\o\r!" >> %Log%
					) ELSE (
						IF %ERRORLEVEL%==8 (
						%run_pdate% "Z --- \E\x\i\t \c\o\d\e \8 \- \N\o\t \e\n\o\u\g\h \m\e\m\o\r\y" >> %Log%
						) ELSE (
							ECHO Recieved error 255 - user stopped running process or exit code unknown! >> %Log%
						)
					)
				)
			)
		)
	)
)
GOTO End

:UpdateBase
ECHO Refreshing base archive
ECHO ******* ******* *******  >> %Log%
%run_pdate% "Z --- \S\t\a\r\t \t\o \u\p\d\a\t\e \a\r\c\h\i\v\e" >> %Log%
%run_7z% u %baseArch% -up0q1r2x1y2z1w0 -w%tmpDir% -i@%IncludeList% -x@%ExcludeList% -xr@%ExcludeRegexp% -bsp2 -ssw -slp -scsWIN -mmt=on -mx5 -ms=off >> %Log%
IF %ERRORLEVEL%==0 (
	%run_pdate% "Z --- \E\x\i\t \c\o\d\e \0 \- \u\p\d\a\t\e \s\u\c\c\e\s\s\f\u\l\l\y \f\i\n\i\s\h\e\d" >> %Log%
	) ELSE (
		IF %ERRORLEVEL%==1 (
		%run_pdate% "Z --- \W\a\r\n\i\n\g\! \R\e\c\i\e\v\e\d\ \e\x\i\t \c\o\d\e \1" >> %Log%
			) ELSE (
				IF %ERRORLEVEL%==2 (
				%run_pdate% "Z --- \E\x\i\t \c\o\d\e \2 \- \F\A\T\A\L \E\R\R\O\R\!" >> %Log%
				) ELSE (
					IF %ERRORLEVEL%==7 (
					%run_pdate% "Z --- \E\x\i\t \c\o\d\e \7 \- \C\o\m\m\a\n\d \p\r\o\m\p\t \e\r\r\o\r!" >> %Log%
					) ELSE (
						IF %ERRORLEVEL%==8 (
						%run_pdate% "Z --- \E\x\i\t \c\o\d\e \8 \- \N\o\t \e\n\o\u\g\h \m\e\m\o\r\y" >> %Log%
						) ELSE (
							ECHO Recieved error 255 - user stopped running process or exit code unknown! >> %Log%
						)
					)
				)
			)
		)
	)
)
GOTO End

:UpdateArchive
ECHO Updtaing existing full backup
ECHO ******* ******* *******  >> %Log%
%run_pdate% "Z --- \S\t\a\r\t \t\o \u\p\d\a\t\e \a\r\c\h\i\v\e" >> %Log%
IF %dw%==7 (SET updArch=%updArch_wn%) ELSE SET updArch=%updArch_dw%

REM --- Check files existence ---
IF EXIST %updArch% DEL /Q %updArch%

REM --- Create incremental archive ---
<nul set /p strTemp=Updating %baseArch% to incremental %updArch% archive
ECHO.
%run_7z% u %baseArch% -u- -up0q0r2x0y2z0w0!%updArch% -w%tmpDir% -i@%IncludeList% -x@%ExcludeList% -xr@%ExcludeRegexp% -bsp2 -ssw -slp -scsWIN -mmt=on -mx5 -ms=off >> %Log%
IF %ERRORLEVEL%==0 (
	%run_pdate% "Z --- \E\x\i\t \c\o\d\e \0 \- \u\p\d\a\t\e \s\u\c\c\e\s\s\f\u\l\l\y \f\i\n\i\s\h\e\d" >> %Log%
	) ELSE (
		IF %ERRORLEVEL%==1 (
		%run_pdate% "Z --- \W\a\r\n\i\n\g\! \R\e\c\i\e\v\e\d\ \e\x\i\t \c\o\d\e \1" >> %Log%
			) ELSE (
				IF %ERRORLEVEL%==2 (
				%run_pdate% "Z --- \E\x\i\t \c\o\d\e \2 \- \F\A\T\A\L \E\R\R\O\R\!" >> %Log%
				) ELSE (
					IF %ERRORLEVEL%==7 (
					%run_pdate% "Z --- \E\x\i\t \c\o\d\e \7 \- \C\o\m\m\a\n\d \p\r\o\m\p\t \e\r\r\o\r!" >> %Log%
					) ELSE (
						IF %ERRORLEVEL%==8 (
						%run_pdate% "Z --- \E\x\i\t \c\o\d\e \8 \- \N\o\t \e\n\o\u\g\h \m\e\m\o\r\y" >> %Log%
						) ELSE (
							ECHO Recieved error 255 - user stopped running process or exit code unknown! >> %Log%
						)
					)
				)
			)
		)
	)
)

:End
ECHO Done!
%run_pdate% "Z --- \D\o\n\e" >> %Log%
ping localhost -w 1000 -n 5 > nul


Вместо окончания


Всегда есть люди, которые против подобных решений, и всеми руками-ногами «за» использование всяких акронисов и прочего «махрового энтерпрайза».

Я же считаю, что решение должно быть соразмерно поставленной задаче, а в моем случае задача — иметь в укромном месте резервную копию файлопомойки, которую можно быстро развернуть — именно этим меня и разочаровал ntbackup.

Собранный пример можно посмотреть на YandexDisk.

Там же — zip-архив для скачивания.
Конструктивная критика, советы, и тем более, тестирование — welcome!
Спасибо за внимание! Всем долгого аптайма, стабильного линка, и конечно, бэкапов под рукой.

Комментарии (34)


  1. Taciturn
    18.09.2017 16:33

    Зачем нужен специальный 7za, требующий двух внешних файлов, если обычный 7z.exe требует одного внешнего файла (7z.dll)?


    1. urfinejuse Автор
      19.09.2017 09:23

      Спасибо за замечание, поправил


  1. rbobot
    18.09.2017 17:11
    -1

    Пост из 2003 года.
    Сейчас все быстрее, проще и удобнее делается из PowerShell, без каких-либо сторонних бинарников.


    1. urfinejuse Автор
      19.09.2017 09:33

      В моем win2k3 он по дефолту отсутствует. К тому же, начинать сразу с PowerShell, имхо, нерационально. Не сомневаюсь, что PowerShell хороший инструмент, но, подчеркну еще раз, инструмент должен быть соразмерен задаче. Когда настанет момент, что возможности BAT исчерпают себя, PowerShell будет первым кандидатом, чтобы продолжить разрабатывать на нем.


    1. Nobody_Admin
      19.09.2017 10:33

      У автора, как я понял, как раз win2k3. На него есть Powershell?


      1. Andrusha
        19.09.2017 11:57

        Есть, но нужно ставить отдельно. Кстати, есть чем-то похожий на авторский скрипт для бэкапа с использованием того же 7-zip. Собственно, его я и заменил на Cobian, так как столкнулся с какими-то проблемами (уже не помню подробностей).


  1. Andrusha
    18.09.2017 20:26
    +1

    Не знаком с fsbackup, но ранее под Windows для бэкапа файлов пользовался Cobian Backup, жмёт тем же 7-zip.


    1. urfinejuse Автор
      19.09.2017 09:35

      Благодарю за наводку! Сегодня же попробую этот софт в деле


  1. slavius
    18.09.2017 21:55

    https://lightbackup.com/
    Программа работает с любыми ОС Windows от WinXP и выше, всех разрядностей.
    Поддерживается теневое копирование тома для чтения заблокированных файлов.
    Для файлов, которые не изменились с прошлого копирования, создаются жёсткие ссылки.
    Позволяет делать резервные копии съёмных носителей без создания теневой копии.
    Работает с сетевыми ресурсами и поддерживает создание хардлинков на них.
    Поддерживаются пути файловой системы любой длины и любой кодировки.
    Полная поддержка юникода, два языка интерфейса (русский и английский).
    Создание общего журнала работы программы и журналов по каждой копии.
    Поддержка тихого режима и автоматического удаления старых копий.
    Не требует никаких сторонних библиотек для своей работы.


  1. osipov_dv
    18.09.2017 21:58

    В 2003 винде был еще нормальный шатный бэкап — ntbackup. Зачем изобретать велосипед, если там было все что нужно? Автор сам виноват, что не продумал схему бэкапа и восстановления до аварии. Ну и то что за бэкапом не следили, это тоже не проблема инструмента.
    Про проверку бэкапов уже даже молчу…


    1. urfinejuse Автор
      19.09.2017 10:09

      osipov_dv, в том, что бэкап оказался неработоспособен, спорить не буду, виноват сам. Но, сравнивая fsbackup для *NIX, и стоковый ntbackup для Windows, я однозначно выберу первый: на днях, проверив бэкап на *NIX сервере, я как и ожидал, увидел что бэкап данных на этом самом сервере работает. Не год, не два, и даже не три, а с 2009 года! Естественно, мне захотелось иметь что то подобное для windows.


      1. osipov_dv
        19.09.2017 16:57

        Если нужно бэкапить только файлы с файлсервера, то есть и был robocopy… а писать под винду на «шеле» как-то не очень правильно.


  1. RumataEstora
    18.09.2017 22:32

    Серию условных операторов можно писать так — визуально уменьшается вложенность, увеличивается читабельность


    if cond1 (
    ) else if cond2 (
    . . . 
    ) else if condN (
    ) else (
    )

    Update:
    К вопросу о программах бекапирования. Есть еще nnBackup весьма шустрый и гибкий.


    1. urfinejuse Автор
      19.09.2017 10:10

      RumataEstora, спасибо за подсказку! Действительно, так код получается более читаемый.


    1. CheBurashka
      19.09.2017 10:32

      Nnbackup платный, сам пользуюсь cobian backup


      1. RumataEstora
        19.09.2017 11:50

        http://www.nncron.ru/register_ru.shtml


        nnBackup бесплатен для граждан стран бывшего СССР при условии частного и некоммерческого использования


        1. CheBurashka
          19.09.2017 12:46

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


  1. davydt
    19.09.2017 10:12
    +1

    Ну раз не хочется махрового энерпрайза, то чем не подошел Cobian Backup? www.cobiansoft.com/index.htm


    1. urfinejuse Автор
      19.09.2017 10:42

      davydt, уже второй хабровчанин советует эту программу.
      Это знак :)
      Надо попробовать


      1. Miller777
        19.09.2017 14:38

        Я третий. Cobian Backup умеет это из коробки.


  1. psbspb
    19.09.2017 10:13

    Интересно, в предыстории у Вас задета важная шара. Т.е. на компьютере бесстрашного пользователя была важная шара? Которую шифратор и полюбил? Или этот шифратор, пробрался на Windows Server по сети и там всё полюбил?

    Вообще, уже несколько лет, для таких целей работает связка из обычного скрипта, который наа сервере запускается по расписанию ночью.
    set src=f:\folder\foldrer
    set dst=e:\b\folder\foldrer
    xcopy /i/e/d/c/y %src% %dst%

    и программы Cobian Backup которая на другом компьютере по расписанию забирает скопированные файлы на сервере. В итоге, на самом сервере есть резервная копия и на другом компьютере.

    Кстати, после недавних событий с шифратором. С испугу, по расписанию, стал выключать сетевуху и включать только на время пока копируются файлы. Чтоб резервный компьютер был вне сети пока все работают и могут нахватать заразы. Потом отказался от этой затеи, а то совсем паранойя)


    1. urfinejuse Автор
      19.09.2017 10:30

      Именно. На компьютере пользователя была важная шара, и ее полюбил шифратор. Когда задумал написать сей велосипед, тоже смотрел в сторону xcopy и robocopy, но 7-Zip для меня предпочтительнее: он умеет считать хэши и выводить список файлов архива, а значит, впоследствие можно сделать инкрементальное копирование по схеме один архив — один инкремент, как это сделано в fsbackup. Сейчас думаю, как это реализовать.
      psbspb, а каким образом Cobian Backup узнаёт, что xcopy завершил свою работу?


      1. psbspb
        19.09.2017 16:20

        >>>а каким образом Cobian Backup узнаёт. К сожалению никаким))) Здесь есть тонкое место. Просто ставлю копирование в 00.00, а в 6.00 cobain забирает.


  1. catexis
    19.09.2017 10:13

    Автору статьи благодарность! Работаю над похожей задумкой. Пишу сервис бекапа на Python на основе 7-zip. Моя идея в веб-морде к сервису бекапа: чтобы можно было посмотреть что сделалось, когда сделалось, статистика и т.п. При этом нет необходимости заходить на сам сервер — работу можно мониторить прямо в окне браузера.


    1. urfinejuse Автор
      19.09.2017 10:32

      catexis, это будет любопытно потестировать! Буду ждать вашего материала по этой разработке.


      1. catexis
        19.09.2017 13:53

        К сожалению у меня «гостевой» аккаунт, поэтому разместить что-либо у меня не получится. В связи с чем — когда будут первые результаты напишу ЛС.


  1. Noa69
    19.09.2017 15:06

    Я же считаю, что решение должно быть соразмерно поставленной задаче, а в моем случае задача — иметь в укромном месте резервную копию файлопомойки, которую можно быстро развернуть — именно этим меня и разочаровал ntbackup.

    robocopy + 7z + однострочный скрипт.


    1. urfinejuse Автор
      19.09.2017 15:59

      Можно и так. Но во-первых, robocopy нет в win2k3 «из коробки», нужно для этого накатывать Windows Resource Kit. Во-вторых, все дело в реализации: что будет делать robocopy и что будет представлять из себя однострочный скрипт?


  1. paranoya_prod
    19.09.2017 16:41
    +1

    Как я понимаю, NTFS ACL и владелец файлов и папок в архив не кладётся?


    1. urfinejuse Автор
      20.09.2017 09:37

      Пока что нет, но вопрос решаем (то есть в процессе решения) — 7z может складывать инфу о правах доступа, но насколько мне известно, только в wim архивы.


  1. Dr_Wut
    20.09.2017 00:30

    Мда… Во-первых совершенно не понятно за что минуснули товарища rbobot-а. Он абсолютно прав — это задача для powershell
    Во-вторых. 2к3 винда? В 2017 году? Серьезно? Даже не смешно. Да, есть варианты когда она нужна, но там точно не стоит задача бекапить шару. А уж если вам так нужно — так сейчас большенство NAS-сов умеют шару раздавать да еще и пользователям с авторизацией через AD.
    В-третьих. Штатный бекапер в 2к3 был шикарен. Все что тот описано делается без проблем на нем
    В-четвертых. Есть куууча софта для бекапа. Как минимум уже назвали Cobain, nnBackup. Есть еще winrar с очень навороченной командной строкой. Есть как минимум служба vss.

    Ну и отдельно, не про автора лично, а про подход. Была проблема, ее не удалось решить стандартными средствами из-за человеческого фактора, так вместо того, чтобы задуматься и устранить причину мы лобаем из глины и палок какую то поделку, которая якобы убирает следствие, да и то не факт.
    А что будете делать когда ваш скрипт в тихую облажается? Как узнаете? Каждый раз проверять глазами? Надоест через месяц. А что с проверкой бекапа? Опять же — ничего. А самое страшное, новички приходят на хабр, читают такие вот истории и делают тоже самое. А потом плачутся что их уволили/депримировали «на гладком месте»

    В общем многоуважаемый автор, я бы на вашем месте убрал бы эту статью себе в бложек/заметки/соцсеть и не выкладывал бы ее на технических ресурсах.


    1. urfinejuse Автор
      20.09.2017 10:27

      >> Он абсолютно прав — это задача для powershell
      Странные у вас представления о правоте — если реализуемо, почему бы и да?
      >>2к3 винда? В 2017 году? Серьезно?
      Да, win2k3. Да, в 2017. Серьезно. Работаю с тем, что есть, и в ближайшее время обновление не предвидится.
      >>Штатный бекапер в 2к3 был шикарен
      Без сомнения хорош, но вот не заладилось у меня с ним (да и не только у меня)
      >> Есть куууча софта для бекапа
      nnBackup бесплатен только для частного использования, winrar также не бесплатен.
      Cobian Backup и vss — согласен, интересная тема, стоит попробовать.
      >>А что будете делать когда ваш скрипт в тихую облажается? Как узнаете?
      Логи же :)
      >> А что с проверкой бекапа? Опять же — ничего.
      Кстати, спасибо за наводку. Стоит включить тест целостности архивов в планировщик.
      >> В общем многоуважаемый автор, я бы на вашем месте убрал бы эту статью
      Начинали с жесткой (но конструктивной) критики, а закончили откровенным хейтерством


      1. Dr_Wut
        21.09.2017 12:04

        Если вы думаете что я не был таким же в начале карьеры — ошибаетесь. Так же пытался делать велосипеды с квадратными колесами. Но попав в похожую ситуацию и огребя достаточно много проблем (при условии что папка была в общем то не сильно нужной — пропали фотки с корпоратива маленькой конторки) я понял что велосипеды могут выйти сильно боком. С тех пор стараюсь их обходить стороной и искать проверенные решения. А вы мало того что сделали странный на мой взгляд вывод из ситуации, так еще и делитесь таким подходом на ресурсе с высоким уровнем доверия


  1. LESHIY_ODESSA
    20.09.2017 16:20

    Мда, сняли статью с языка, сам хотел писать. Мои наработки и добавления.

    @backup-list.txt — где «backup-list.txt» файл со списком путей для бэкапа. К примеру:
    C:\Users\Администратор\Desktop\
    D:\TEMP\*.???
    D:\TEMP\Programs\SumatraPDF\
    C:\Program Files\Media Player Classic HomeCinema\Download AC3Filter.url


    *.??? — Мы не хотим целиком резервировать папку (подпапки), но хотим зарезервировать все файлы находящиеся в ней.

    -x@ignore.txt — список пропускаемых файлов (ignore.txt). А вот тут немного хитрее. Абсолютные пути не работают. Работают пути как они отображаются в архиве.

    *.mp3
    Users\Администратор\AppData\Roaming\Mozilla\Firefox\Crash Reports\
    Users\Администратор\AppData\Roaming\Thunderbird\Crash Reports\
    Program Files\Mozilla Thunderbird\ALEX_profiles\Cache\
    Program Files\Mozilla Thunderbird\ALEX_profiles\cache2\


    Так же у меня в этом же файле настроена отправка архива на гугл диск с помощью консольной утилиты Google Drive CLI Client. Скорость правда не ахти, всего 5мбит/с, но для гигабайтного архива вполне нормально. Отдельный разговор как получить постоянный токен.
    Создать токен командой — gdrive-windows-x64.exe about
    В терминале выдаст URL который копируем в браузер и запускаем, логинимся, даем доступ, получаем ключ.
    Затем находим файл в C:\Users\Администратор\AppData\Roaming\.gdrive в котором находим «refresh_token». И чтобы была полная портабельность, избавляемся от папки .gdrive.

    B:\BACKUP\gdrive-windows-x64.exe --config B:\BACKUP\ --refresh-token "1/riеqsg5J78Ftq4WmxtРtc0w6Iрhf3kJX7oGwljFE" upload --parent 0Bx0I330bQqVB19PdHRX1hEGW B:\BACKUP\backup.7z


    --refresh-token — взяли заранее в папке .gdrive.
    --config B:\BACKUP\ — путь к программе.
    --parent — имя папки на гугл драйве.