7-zip
В нём нет возможности хранить версионность файлов в одном архиве. Однако, можно сделать несколько diff-архивов и тогда каждый из них будет хранить свою версию файлов. Другими словами, каждый Чаптер (chapter, терминология ARJ) располагается в отдельном файле. Точнее, будет один базовый архив и множество diff-архивов с изменениями относительно базового.
Анти-файл
Даже пригодился "анти-файл" (Анти-пункт, по терминологии 7-zip). Когда пользователь удалил файл, но в базовом архиве этот файл есть, то в diff-архиве создаётся "анти-файл". Грубо говоря, после распаковки базового архива файл создаётся на диске - ведщь в базовом архиве этот файл присутствует. А вот при распаковке diff-архива, анти-файл удаляет файл на диске.
Пишем батник
Батник решил написать мой коллега, nWhite.
Текст батника ниже. Краткий перечень интересных моментов:
- "Самозапускаемый" батник для сворачивания в трей. Можно конечно написать еще один батник который будет запускай этот большой и обойтись без такого изврата, но это будет уже два батника:
REM При первом вызове батника он перезапускает себя,
REM чтобы запуститься свернутым и с низким приоритетом:
IF Not %1.==SecondStart. (
Start /Min /Low %~f0% SecondStart
Exit
)
- Заголовок батника
ChCP 1251>Nul
Title "Архивация данных пользователя"
- Создаём базовый архив
%ArchiverEXEPath% A %BaseArcPath% -ssw %ExcludeExt% %BackupFolder%\* -ms=off -mx=1 -mtc=on
- Создаём diff-архив на основе базового архива
%ArchiverEXEPath% U %BaseArcPath% -ssw %ExcludeExt% -u- -up0q3r2x2z0!%DiffArcPath% %BackupFolder%\* -ms=off -mx=1 -mtc=on
Вот полный текст:
@Echo On
REM **********************************************************************REM * Архивация данных пользователя (документы и рабочий стол) v1.0 beta *REM * почти копирайт Nikoluk/nWhite 2010 *REM * Издание первое, не дополненное и не переработанное *REM **********************************************************************
REM При первом вызове батника он перезапускает себя,REM чтобы запуститься свернутым и с низким приоритетом:IF Not %1.==SecondStart. (Start /Min /Low %~f0% SecondStartExit)
ChCP 1251>NulTitle "Архивация данных пользователя"
REM Парсим дату и время для использования их в переменных Year, Month и т.д.Call :SetCurDateTimeREM Определяем расположения стандартных пользовательских папокCall :SetUserEnvInfo
REM *** ОПРЕДЕЛЯЕМ ПЕРЕМЕННЫЕ *******************************Set ArchiverEXEPath="\\Osprey\GPO\7-Zip\7z.exe"Set ArcFolderPath="\\Osprey\Archives\%UserName%"REM Путь к пользовательскому подробному логу:Set LogPath="%ArcFolderPath%\log.txt"REM Путь к общему краткому логу:Set CommonLogPath="\\Osprey\Archives\CommonLog.txt"
Echo [%DATE% - %TIME%] Start User Backup [User: %UserName%; PC: %ComputerName%] >> %CommonLogPath%
REM Список исключений, всякую лабудень не архивим:Set ExcludeExt=-XR!*.avi -XR!*.mkv -XR!*.mov -XR!*.vob -XR!*.flv -XR!*.3gp -XR!*.wmv -XR!*.asf -XR!*.mpg -XR!*.mp4 -XR!*.mp3 -XR!*.wav -XR!*.flac -XR!*.wv -XR!*.ape -XR!*.alac -XR!*.tmp
Set DeskBaseArcPath="%ArcFolderPath%\%Year%-%Month% [%UserName%] Desktop Base.7z"Set DeskDiffArcPath="%ArcFolderPath%\%Year%-%Month%-%Day% [%UserName%] Desktop Diff.7z"Set DocsBaseArcPath="%ArcFolderPath%\%Year%-%Month% [%UserName%] Documents Base.7z"Set DocsDiffArcPath="%ArcFolderPath%\%Year%-%Month%-%Day% [%UserName%] Documents Diff.7z"REM *********************************************************
IF Not Exist %ArcFolderPath% (MkDir %ArcFolderPath%IF Not %ErrorLevel%==0 (Echo ERROR! Can't create archive folder! [%ArcFolderPath%] ErrorLevel=%ErrorLevel%PauseExit))
Echo ----------------------------------------------------------------------------- >> %LogPath%Echo _ >> %LogPath%Echo [%DATE% - %TIME%] ^> Start User Backup [User: %UserName%; PC: %ComputerName%] >> %LogPath%
REM Проверимс, есть ли архиватор по заданному пути:IF Not Exist %ArchiverEXEPath% (Echo Archiver EXE NOT FOUND! [%ArchiverEXEPath%] >> %LogPath%GoTo TheEND)
Set BackupName=DESKTOPSet BackupFolder=%DesktopPath%Set BaseArcPath=%DeskBaseArcPath%Set DiffArcPath=%DeskDiffArcPath%Call :Backup
Set BackupName=DOCUMENTSSet BackupFolder=%MyDocsPath%Set BaseArcPath=%DocsBaseArcPath%Set DiffArcPath=%DocsDiffArcPath%Call :Backup
:TheENDEcho [%DATE% - %TIME%] ^< End User Backup >> %LogPath%
REM Вот и сказочке конец, а кто бекапит - маладэц! =)Exit
REM ***********************************************************************REM *************************** ПРОЦЕДУРЫ *********************************
:BackUpREM *** Процедура архивации *********************************REM *** Перед вызовом дополнительно нужно задать следующие переменные:REM BackupName - название бекапа, которое будет фигурировать в логе.REM BackupFolder - путь к архивируемой папке.REM BaseArcPath - путь к базовому архиву.REM DiffArcPath - путь к дифференциальному архиву.Echo [%DATE% - %TIME%] Backuping user %BackupName%... [%BackupFolder%] >> %LogPath%
IF Not Exist %BackupFolder% (Echo [%DATE% - %TIME%] Folder %BackupFolder% NOT FOUND! >> %LogPath%GoTo EndProc)
REM Посмотрим, есть ли у нас базовый архивIF Not Exist %BaseArcPath% (Echo [%DATE% - %TIME%] Search the BASE %BackupName% archive [%BaseArcPath%]... NOT FOUND. Creating BASE archive... >> %LogPath%GoTo CreateBaseArc) ELSE (Echo [%DATE% - %TIME%] Search the BASE %BackupName% archive [%BaseArcPath%]... FOUND. >> %LogPath%IF Not Exist %DiffArcPath% (Echo [%DATE% - %TIME%] Search the DIFFERENTIAL %BackupName% archive [%DiffArcPath%]... NOT FOUND. Creating DIFFERENTIAL archive... >> %LogPath%GoTo CreateDiffArc) ELSE (Echo [%DATE% - %TIME%] Search the DIFFERENTIAL %BackupName% archive [%DiffArcPath%]... FOUND. No need %BackupName% backup. >> %LogPath%))
REM Кажися, ниче архивить не надо (все украдено до нас). Валим отсюда...GoTo EndProc
:CreateBaseArc%ArchiverEXEPath% A %BaseArcPath% -ssw %ExcludeExt% %BackupFolder%\* -ms=off -mx=1 -mtc=onSet ErrLevel=%ErrorLevel%Call :SetErrorDescriptionEcho [%DATE% - %TIME%] Done. ErrorLevel = %ErrLevel%, %ErrorDescription% >> %LogPath%IF Not Exist %BaseArcPath% (REM Вот ужасть-то какая, а архива-то нету...[%DATE% - %TIME%] Echo ERROR! Archive %BaseArcPath% NOT FOUND! >> %LogPath%)GoTo EndProc
:CreateDiffArc%ArchiverEXEPath% U %BaseArcPath% -ssw %ExcludeExt% -u- -up0q3r2x2z0!%DiffArcPath% %BackupFolder%\* -ms=off -mx=1 -mtc=onSet ErrLevel=%ErrorLevel%Call :SetErrorDescriptionEcho [%DATE% - %TIME%] Done. ErrorLevel = %ErrLevel%, %ErrorDescription% >> %LogPath%IF Not Exist %DiffArcPath% (REM Вот ужасть-то какая, а архива-то нету...Echo [%DATE% - %TIME%] ERROR! Archive %DiffArcPath% NOT FOUND! >> %LogPath%)GoTo EndProc
:EndProcExit /b
:SetCurDateTimeREM Парсинг даты и времениFor /f "Tokens=1-3 Delims=./-" %%A In ("%Date%") Do (Set Day=%%ASet Month=%%BSet Year=%%C)For /f "Tokens=1-3 Delims=:," %%A In ("%Time%") Do (Set Hours=%%ASet Minutes=%%BSet Seconds=%%C)Exit /b
:SetUserEnvInfoREM *** Определение расположения стандартных пользовательских папок ***For /f "Tokens=2*" %%i In ('Reg Query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v Desktop ^| FindStr /s /i Reg_sz') Do (Set DesktopPath="%%j")REM Если путь к десктопу начинается с %UserProfile%,REM сделаем обходной маневр, чтобы путь расшифровался.REM (если в пути используется какая-либо другаяREM переменная среды - сори, не повезло, "кина не будет")IF Not %DesktopPath%.==. (IF /i %DesktopPath:~2,11%==UserProfile (Set DesktopPath="%UserProfile%%DesktopPath:~14,300%))For /f "Tokens=2*" %%i In ('Reg Query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v Personal ^| FindStr /s /i Reg_sz') Do (Set MyDocsPath="%%j")IF Not %MyDocsPath%.==. (IF /i %MyDocsPath:~2,11%==UserProfile (Set MyDocsPath="%UserProfile%%MyDocsPath:~14,300%))Exit /b
:SetErrorDescriptionREM Расшифровка ErrorLevel'а 7-Zip'а:IF %ErrLevel%==0 Set ErrorDescription=No ErrorsIF %ErrLevel%==1 Set ErrorDescription=Warning (Non fatal error(s)). For example, one or more files were locked by some other application, so they were not compressed.IF %ErrLevel%==2 Set ErrorDescription=Fatal errorIF %ErrLevel%==7 Set ErrorDescription=Command line errorIF %ErrLevel%==8 Set ErrorDescription=Not enough memory for operationIF %ErrLevel%==255 Set ErrorDescription=User stopped the processExit /b
1 комментарий:
Странно. Я через 10 лет использую этот скрипт для бекапа кода. У клиента сдох Azure DevOps - а код лучше хоть как-то бекапить.
Отправить комментарий