提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
在日常工作中,做好数据备份是一项重要的习惯,虽然繁琐,但出问题时却可救命。
当然,简单的方式就是通过脚本命令去定时执行。不过大部分开发者,可能只实现了基本的操作,而对一些细节疏于处理。
我一直认为,一个好的程序/脚本,除了本身的编码风格之外,代码/脚本的完整性、可重用性、记录的可跟踪性和结果可视化,也都非常重要。在漫长的编码人生之路上,认真的对待每一行代码,并且在今后的日子里,也能不断的发挥作用,那是极其棒的一件事情。
这里记录一下一个windows环境下的bat备份脚本
BAT备份
@REM ======================================================================
@REM This script is using to SVN Repositories to remote server
@REM
@REM Version 1.0
@REM ======================================================================
@echo off
@REM config script run mode: 0 basic test; 1 +ftp putting; 2 +local backup; 3 +rsync files;
set run_time=1
@REM initiate local variables
set LOG_FILE=backup_svn.log
set ERR_FILE=backup_svn.err
set m_startdate=%date:~0,10%
set m_curtime=%time:~0,8%
set m_startsecond=%time:~6,2%
set m_startminute=%time:~3,2%
set m_starthour=%time:~0,2%
set /a m_curyear=%date:~0,4%
set /a m_curmonth=1%date:~5,2% - 100
@REM Iintiate ftp configration
set FTP_FILE=ftp.up
set FTP_SERVERIP=[FTP服务器IP地址]
set FTP_ROOTPATH=\backup\
set FTP_USER=[FTP用户]
set FTP_PASSWORD=[FTP密码]
set FTP_TRANS=binary
set FTP_PUTCMD=put
set FTP_QUIT=bye
set FTP_REMOTEPATH=%FTP_SERVERIP%%FTP_ROOTPATH%
@REM initiate the parameters of backup which will write into Finshed file
set m_Project=SVN
set m_Result=Success
set m_Location=NAS
set m_FileName=Repositories
set m_FileSize=23.2G
set m_StartTime=%time:~0,8%
set m_EndTime=%time:~0,8%
set m_TimeDuration=
set m_ErrFile=none
set m_ErrMessage=none
set m_FinishedFile=%m_Project%.Finished
@REM help entrance
if "%1"=="/?" goto :Help
if "%1"=="-h" goto :Help
if "%1"=="-help" goto :Help
if "%1"=="/h" goto :Help
if "%1"=="/help" goto :Help
@REM ======================================================================
@REM 延迟环境变量扩展,用于数值计算
@REM ======================================================================
setlocal enabledelayedexpansion
@REM ======================================================================
@REM 1. Start and clear the legacy files and create finished file
@REM ======================================================================
echo ^<BACKUP SVN LOGFILE START^> > %LOG_FILE%
echo *** ================================================================== >> %LOG_FILE%
echo *** Log file: %LOG_FILE% >> %LOG_FILE%
echo *** Start Date: %m_startdate% >> %LOG_FILE%
echo *** Start Time: %m_curtime% >> %LOG_FILE%
echo *** Remote log path: %FTP_REMOTEPATH% >> %LOG_FILE%
echo *** ================================================================== >> %LOG_FILE%
echo 1. Start backup files, clear lagcy files >> %LOG_FILE%
del /f /q *.err
del /f /q *.Finished
@REM 为解决赋值遇到0开始出错的情况,在字符前加上1,再减去相应的值(2位则减100)
set /a m_startsecond=1%time:~6,2% - 100
set /a m_startminute=1%time:~3,2% - 100
set /a m_starthour=%time:~0,2%
echo Backup start: %m_starthour%:%m_startminute%:%m_startsecond%
@REM ======================================================================
@REM 2. backup SVN files to local directory first
@REM ======================================================================
echo 2. Backup files to local directory >> %LOG_FILE%
if %run_time% GEQ 2 (
@REM add your process
echo do not need to back local files >> %LOG_FILE%
)
@REM ======================================================================
@REM 3. Using rsync to backup file to NAS server
@REM ======================================================================
echo 3. Copy files to remote server: %m_Location% >> %LOG_FILE%
if %run_time% GEQ 3 (
for /f "delims=" %%i in ('C:\cwRsync\bin\rsync -az --delete /cygdrive/f/Repositories rsync@192.168.20.200::Public/svn ^< C:\cwRsync\bin\user.txt') do (
echo rsync svn failed: %%i >> %LOG_FILE%
set m_Result=Failed
set m_ErrMessage=%ErrMessage%+%%i
)
)
@REM ======================================================================
@REM 4. Generate Finished file
@REM ======================================================================
set m_startY=%date:~0,4%
set m_startM=%date:~5,2%
set m_startD=%date:~8,2%
set m_FinishedFile=%m_startY%-%m_startM%-%m_startD%_%m_Project%_%m_Result%.Finished
echo 4. Write finished file: %m_FinishedFile% >> %LOG_FILE%
@REM update endtime
set m_EndTime=%time:~0,8%
set /a m_endsecond=1%m_EndTime:~6,2% - 100
set /a m_endminute=1%m_EndTime:~3,2% - 100
set /a m_endhour=%m_EndTime:~0,2%
echo Get start time: %m_starthour%:%m_startminute%:%m_startsecond% >> %LOG_FILE%
echo Get finish time: %m_endhour%:%m_endminute%:%m_endsecond% >> %LOG_FILE%
@REM calculate the cost of seconds
if %m_endsecond% LSS %m_startsecond% (
set /a m_endsecond+=60
set /a m_endminute-=1
)
set /a m_dursecond=%m_endsecond% - %m_startsecond%
@REM echo calculate the cost of seconds: %m_dursecond% >> %LOG_FILE%
@REM calculate the cost of minutes
if %m_endminute% LSS %m_startminute% (
set /a m_endminute+=60
set /a m_endhour-=1
)
set /a m_durminute=%m_endminute% - %m_startminute%
@REM echo calculate the cost of minutes: %m_durminute% >> %LOG_FILE%
@REM calculate the cost of hours
if %m_endhour% LSS %m_starthour% (
set /a m_endhour+=24
)
set /a m_durhour=%m_endhour% - %m_starthour%
@REM echo calculate the cost of hours: %m_durhour% >> %LOG_FILE%
@REM get the duration time
set m_TimeDuration=%m_durhour%:%m_durminute%:%m_dursecond%
@REM record the parameters in Finshed file
echo [Basic] > %m_FinishedFile%
echo Project=%m_Project% >> %m_FinishedFile%
echo Result=%m_Result% >> %m_FinishedFile%
echo Location=%m_Location% >> %m_FinishedFile%
echo FileName=%m_FileName% >> %m_FinishedFile%
echo FileSize=%m_FileSize% >> %m_FinishedFile%
echo StartTime=%m_starttime% >> %m_FinishedFile%
echo EndTime=%m_EndTime% >> %m_FinishedFile%
echo TimeDuration=%m_TimeDuration% >> %m_FinishedFile%
echo [Err] >> %m_FinishedFile%
echo ErrFile=%m_ErrFile% >> %m_FinishedFile%
echo ErrMessage=%m_ErrMessage% >> %m_FinishedFile%
@REM ======================================================================
@REM 5. Put the finished file to remote server
@REM ======================================================================
echo 5. Put finished file to remote server >> %LOG_FILE%
set FTP_REMOTEPATH=%FTP_ROOTPATH%%m_curyear%^\%m_curmonth%
echo remote path: %FTP_SERVERIP% %FTP_REMOTEPATH% >> %LOG_FILE%
if %run_time% GEQ 1 (
echo open %FTP_SERVERIP%> %FTP_FILE%
echo %FTP_USER%>> %FTP_FILE%
echo %FTP_PASSWORD%>> %FTP_FILE%
echo cd %FTP_REMOTEPATH%>> %FTP_FILE%
echo %FTP_TRANS%>> %FTP_FILE%
echo %FTP_PUTCMD% %m_FinishedFile%>> %FTP_FILE%
echo %FTP_QUIT%>> %FTP_FILE%
for /f "delims=" %%i in ('ftp -s:%FTP_FILE%') do (
echo put file to remote: %%i >> %LOG_FILE%
)
del /q %FTP_FILE%
)
echo *** ================================================================== >> %LOG_FILE%
echo *** Finished Time: %m_EndTime% >> %LOG_FILE%
echo *** Duration Cost: %m_durhour%h %m_durminute%m %m_dursecond%s >> %LOG_FILE%
echo *** ================================================================== >> %LOG_FILE%
echo ^<BACKUP SVN LOGFILE END^> >> %LOG_FILE%
@REM ======================================================================
@REM Help usage and exit
@REM ======================================================================
exit /B 0
:Help
echo This script is using to backup svn files to remote server
echo Usage:
echo backup_svn.bat
exit /B 1
这个脚本我分成了5个部分
1. 本地的清理
2. 本地文件的复制/备份
3. 把本地文件备份到远程服务器(这里采用异地NAS)
此部分最重要的是用了rsync这个命令,做增量备份
4. 把备份状况总结为一个.Finshed文件
这里关于耗时的计算花了很多时间,一度想放弃,但考虑到程序执行时间是一个蛮重要的信息,还是把它计算出来好。
BAT中不像linux shell那样,可以直接得到以基准时间后的秒 数,可以直接计算,所以只能单个进行时分秒的加减。其中对于分、秒的赋值,又可能遇到0开头的状况,所以需要做额外处理(这里我用了前面加1,再减100的方法),小时不需要这样操作。
5. 把Finished文件上传到ftp服务器的指定目录(进行后续分析和可视化显示)
DOS中ftp操作还是比较友好,可以直接把命令写到一个文件中,然后用 ftp -s:file 来操作即可。在shell中的话,则可以用 << EOF 的方式,后面加ftp命令。
在脚本执行的时候,我用了run_time这个变量来控制主要几个部分的执行,旨在便于调试。同时,脚本执行的过程会生成一个 .log的文件,便于查看最后执行的结果。若有问题从log中能及时发现,可以帮助调试速度。另外,看整齐的log的也是一种享受,不知道程序员兄弟们是否有同样的感受。