|

楼主 |
发表于 2005-1-24 15:58:08
|
显示全部楼层
系统备份脚本 [ 第2次更新}
首先非常感谢kiron提出的意见。根据这些意见,代码进行了改动,增加了-h, --help选项,输出完整的帮助文档;增加了log文档,也就是说在备份的时候会自动生成一个backup-日期-时间.log的文档来记录本次备份的信息(不是用户自己写的注释文档!);如果备份过程中出现任何错误都会输出该错误并执行相应命令的help;如果检测到用户目录下没有配置文件存在,会提示用户创建,并要求用户对其进行更改;解决了分段备份中的几个小bug。
下面是代码:
- #!/bin/bash
- # This script makes the backup of the system. For more details, use
- # backup.sh --help
- # Written by Neo Anderson <ZeeGeek@gmail.com>
- # Jan 18 2005
- # the following four variables are specified by users
- MTOGGLE=$1
- # set DEST to the destination which you want all the backup files go.
- # CAUTION, there's no default value for this variable, so you MUST
- # specify it in the config file.
- DEST=''
- # PART_TOGGLE specifies the size of each part of the target backup
- # file, 0 means don't cut, any number bigger than 0 will be treated as
- # Kilobytes of each part of the file.(default is 0)
- PART_TOGGLE=0
- # LOG_TOGGLE means whether or not you want to have a log when you
- # backup. (default is no)
- LOG_TOGGLE='no'
- asroot() {
- # check if the user is running this script as root
- if [ "$(whoami)" != 'root' ]
- then
- echo "Please run this script as root!"
- exit
- fi
- }
- usercheck() {
- echo "DEST is $DEST"
- echo "PART_TOGGLE is $PART_TOGGLE"
- echo "LOG_TOGGLE is $LOG_TOGGLE"
- echo -n "are they correct? (y/n)"
- read -n 1 CHECK_ANS
- echo
- if [ $CHECK_ANS != 'y' ]
- then
- echo "please edit the config file"
- exit
- fi
- }
- initiate() {
- # check if the destination directory exists
- if [ ! -d $DEST ]
- then
- echo "Destination directory not exists. Please create it before backup"
- exit
- fi
- cd /
- }
- config() {
- echo -n "Config file not exist. Do you want me to create it for you? (y/n)"
- read CONFIG_ANS
- if [ $CONFIG_ANS == 'y' ]
- then
- echo "DEST: /path/to/put/the/backup/file" > $HOME/.backuprc
- echo "SP:" >> $HOME/.backuprc
- echo "freq /things/you/want/to/backup [options for tar]" >> $HOME/.backuprc
- echo "The config file has been created, it's called .backuprc in your home directory. YOU MUST EDIT IT BEFORE USE!"
- echo -n "Edit now? (y/n)"
- read EDIT_ANS
- if [ $EDIT_ANS == 'y' ]
- then
- $EDITOR $HOME/.backuprc
- readconf
- else
- exit
- fi
- else
- exit
- fi
- }
- readconf() {
- # whether or not source path part has reached
- SP='false'
-
- exec 6<> $HOME/.backuprc # redirect FD 6 to the file .backup
-
- while read INPUT <&6 # read the config file line by line
- do
- if [[ "`echo $INPUT | grep SP:`" || $SP == 'true' ]]
- then
- # read one more time to skip "SP:"
- if [ $SP == 'false' ]
- then
- read INPUT <&6
- # ask user to check
- usercheck
- # record log file
- echo "All options correct" >> $BACKUP_LOG
- # initiating
- initiate
- # record log file
- echo "Destination directory exists" >> $BACKUP_LOG
- # toggle on
- SP='true'
- fi
-
- # get the frequency
- TOGGLE="`echo $INPUT | awk '{ print $1 }'`"
- # get the source path and options passed to tar
- SOURCE=${INPUT#$TOGGLE}
-
- # check the toggle provided by user when running this
- # script
- case $MTOGGLE in
- weekly)
- # if the toggle specified by user
- # matches the toggle for each source,
- # then back it up
- if [ $MTOGGLE == $TOGGLE ]
- then
- backup
- else
- continue
- fi
- ;;
- monthly)
- if [ $MTOGGLE == $TOGGLE ]
- then
- backup
- else
- continue
- fi
- ;;
- all)
- backup
- ;;
- *)
- usage
- exit
- ;;
- esac
- else
- TEMP="`echo $INPUT | awk '{ print $1 }' | sed s/.$//`"
- TEMP_V="`echo $INPUT | awk '{ print $2 }'`"
- case $TEMP in
- DEST)
- DEST=$TEMP_V
- BACKUP_LOG="$DEST/backup-`date +%b%d%Y-%H%M`.log"
- # record log file
- echo "----- Start of log file -----" >> $BACKUP_LOG
- echo "Config file exists" >> $BACKUP_LOG
- echo "DEST read" >> $BACKUP_LOG
- ;;
- PART_TOGGLE)
- PART_TOGGLE=$TEMP_V
- # record log file
- echo "PART_TOGGLE read" >> $BACKUP_LOG
- ;;
- LOG_TOGGLE)
- LOG_TOGGLE=$TEMP_V
- # record log file
- echo "LOG_TOGGLE read" >> $BACKUP_LOG
- ;;
- RM_OLD)
- RM_OLD=$TEMP_V
- # record log file
- echo "RM_OLD read" >> $BACKUP_LOG
- ;;
- *)
- echo "unrecognized option $TEMP"
- usage
- exit
- ;;
- esac
- fi
- done
- # record log file
- echo >> $BACKUP_LOG
- echo >> $BACKUP_LOG
- echo "all jobs done successfully" >> $BACKUP_LOG
- }
- backup() {
- # record log file
- echo >> $BACKUP_LOG
- echo "----------" >> $BACKUP_LOG
- echo >> $BACKUP_LOG
- SOURCE_PATH="`echo $SOURCE | awk '{ print $1 }'`"
- # record log file
- echo "SOURCE PATH is $SOURCE_PATH" >> $BACKUP_LOG
- DEST_NAME="$DEST/`basename $SOURCE_PATH`"
- # record log file
- echo "DEST NAME is $DEST_NAME" >> $BACKUP_LOG
- DEST_TAR="$DEST_NAME-`date +%b%d%Y-%H%M`.tar.gz"
- # record log file
- echo "DEST TAR is $DEST_TAR" >> $BACKUP_LOG
- SIZE=$PART_TOGGLE
- if [ $PART_TOGGLE == 0 ]
- then
- tar czvfp $DEST_TAR $SOURCE >> $BACKUP_LOG 2>&1 # backup
- if [ $? != 0 ]
- then
- echo "Error making backup. Errors are stored in $BACKUP_LOG"
- tar --help
- exit
- fi
- md5sum $DEST_TAR > $DEST_NAME.md5 2>>$BACKUP_LOG # make md5sum
- if [ $? != 0 ]
- then
- echo "Error making md5sum of backup. Errors are stored in $BACKUP_LOG"
- md5sum --help
- exit
- fi
- else
- COUNTS=$[$PART_TOGGLE * 2]
- # record log file
- echo "COUNTS is $COUNTS" >> $BACKUP_LOG
- for ((a=1;;a++))
- do
- # record log file
- echo >> $BACKUP_LOG
- if [ "$SIZE" -ge "$PART_TOGGLE" ]
- then
- TEMP_DEST_TAR="$DEST_TAR"."$a"
- # record log file
- echo "TEMP DEST TAR is $TEMP_DEST_TAR" >> $BACKUP_LOG
- tar czvfp - $SOURCE | dd of=$TEMP_DEST_TAR \
- skip=$[$COUNTS * $[$a - 1]] \
- count=$COUNTS >> $BACKUP_LOG 2>&1
- if [ $? != 0 ]
- then
- echo "Error making backup. Errors are stored in $BACKUP_LOG"
- dd --help
- exit
- fi
- md5sum $TEMP_DEST_TAR >> $DEST_NAME.md5 2>>$BACKUP_LOG
- if [ $? != 0 ]
- then
- echo "Error making md5sum of backup. Errors are stored in $BACKUP_LOG"
- md5sum --help
- exit
- fi
- # size of last backuped part of file
- SIZE="`ls -lk $TEMP_DEST_TAR | awk '{ print $5}'`"
- # record log file
- echo "SIZE is $SIZE" >> $BACKUP_LOG
- else
- break
- fi
- done
- fi
-
- # record log file
- echo "backup succeeded" >> $BACKUP_LOG
- ls -lRa $SOURCE_PATH > $DEST_NAME.list # keep a list of this source
- # record log file
- echo "file list made" >> $BACKUP_LOG
-
- # make a log file
- if [[ $LOG_TOGGLE == 'yes' || $LOG_TOGGLE == 'Yes' || \
- $LOG_TOGGLE == 'YES' || $LOG_TOGGLE == 'Y' || \
- $LOG_TOGGLE == 'y' ]]
- then
- echo "# Log file for $DEST_NAME" > $DEST_NAME
- echo "# Written by `whoami`" >> $DEST_NAME
- echo "# `date +"%b %d %Y"`" >> $DEST_NAME
- $EDITOR $DEST_NAME.log
- # record log file
- echo "log file made" >> $BACKUP_LOG
- fi
- }
- usage() {
- echo 'Usage: backup.sh [OPTION]'
- echo 'Options:'
- echo ' all backup all the entries specified in the config file'
- echo ' weekly backup entries start with 'weekly' in the config file'
- echo ' monthly backup entries start with 'monthly' in the config file'
- echo ' -h, --help display the help and exit'
- echo
- echo 'Config file:'
- echo 'config file must be present in your home directory with
- the name of .backuprc. There are four options you can specify in
- it. They are DEST, PART_TOGGLE, LOG_TOGGLE and SP. The meaning
- for them are "destination directory you want all backup files
- in", "the size of each part of the target backup file, 0 means
- do not cut, any number bigger than 0 will be treated as
- Kilobytes of each part of the file.(default is 0)", "whether or
- not you want to have a log when you backup. (default is no)",
- "the sign of telling the script the following lines are pathes
- you want to be backuped", respectively. Each option name must be
- followed by a colon and a space, then the value. The options
- DEST and SP have to exist in order to have the script work. The DEST
- option must comes at the beginning and SP must be put at the end of the
- config file.'
- echo
- echo 'Example of .backuprc:'
- echo ' DEST: /mnt/usbc'
- echo ' PART_TOGGLE: 10240'
- echo ' LOG_TOGGLE: yes'
- echo ' SP:'
- echo ' weekly /root'
- echo ' monthly /etc'
- }
- # Start of the script
- # check if the script is run as root
- asroot
- # check the existance of the config file
- if [ ! -f $HOME/.backuprc ]
- then
- config
- fi
- # help
- if [[ $1 == '--help' || $1 == '-h' ]]
- then
- usage
- elif [[ $1 == 'all' || $1 == 'weekly' || $1 == 'monthly' ]]
- then
- readconf
- else
- usage
- fi
复制代码
有个问题没解决,想请大家指教:当进行分段备份时,为何重定向不起作用,输出仍然会跑到屏幕上,而不是我指定的log文件里。如果不是分段备份就没这个问题。 |
|