linux系统备份脚本

前言

  之前写过<<linux系统简单备份的脚本>>, 最开始一直用着,后来觉得有必要改进下它,不管是从操作方式上还是脚本的工作方式上。之所以这么看重备份,是因为我经历过磁盘损坏的痛苦,花了1500元才勉强将数据拯救回来。我期望尽量每周备份,期望备份的目的地存储了当前系统的完整镜像,也就是说我能够从备份盘启动,且启动后系统的操作方式、已安装的软件及软件的配置以及文件的布局和当前的一模一样,每周我只需要增量备份当前的修改到备份盘。我不喜欢造轮子,但是在linux下没有现成的适合我的,于是就有了下面的备份脚本(其实只是基于rsync进行了一个封装啦)。

备份准备

注意: 当前还没有加入自动镜像系统的功能,所以如果想镜像系统,需要手动这样操作(这里只是简要描述):

基本步骤:

  1. 准备一块大于或等于当前系统所在盘的硬盘,然后给它分区,分区的结构要和原系统的分区结构保持一模一样,这个可以先通过fdisk -l记录下源磁盘的分区起始分区和结束分区;
  2. 分区后再格式化每个分区,每个分区的文件系统也尽量和要备份的磁盘分区相同;
  3. 挂载相应的分区
  4. 启动backup备份,备份的时候主要有些目录需要跳过,比如sys proc,另外如果/home目录是独立分区,那么备份/分区的时候也要跳过它,这些需要跳过的目录可以在backup启动的时候设置!
  5. 当备份完需要的分区后(这里假设备份了/分区和/home分区)后,在备份磁盘的/所挂载的分区下创建home sys proc目录
  6. 将备份磁盘home分区挂载到备份磁盘/分区的home下,并将当前的虚拟文件系统挂载到备份根分区下相应的目录,执行:
    mount –o bind /proc /mnt/proc
    mount –o bind /sys /mnt/sys (这里假设备份磁盘的/分区挂载在/m下)
    然后执行chroot 备份磁盘的/分区所挂载目录, 进入后执行grub_install grub_update来安装bootloader
  7. 做一些额外的配置文件修改,比如/etc/fstab文件里面可能是用uuid来挂载的,但是因为我们是从源系统备份过来的,所以需要修改成备份磁盘分区的uuid

btw: 备份的时候,尽量在第三方系统里面去备份想备份的磁盘

最新的代码请通过git访问:

git@bitbucket.org:rongpmcu/backup-script-shell.git

备份源码

这是脚本程序backup:

#!/bin/bash
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# Author: rongp
# email:  rongpmcu#gmail.com
# Date: 2014/10/26
# 备份程序
# 特点:
# 主要支持unix类系统下, 支持符号链接
# 支持增量备份
# 添加备份条目时,支持文件名含有空格 但是不能出现含有@#@的文件名条目
# 添加备份条目时,支持直接托拽文件或者文件夹作为文件名路径
# 支持每次备份的变更备份,方便用于人工操作失误后的修复
# 支持添加规则用于剔除某些文件 格式请参考rsync的PATTERN部分

# 准备加入特性:
# 增加备份条目添加别名,这样方便查看
# 增加备份日志
# 增加备份时添加用户日志
# 参数解析还是需要加入多参数同时解析(bb bf等选项应该分开化,提供机制,而非策略)
# 网络备份(由于基于rsync, 很容易加入该功能,但暂时没加入)

SHELL=/bin/bash
backup_cfg_path=/etc
backup_cfg=$backup_cfg_path/backup.cfg
db_path=
db_pathname=
inc_path=

XECHO=1

_help()
{
    echo -e "$0 [option]\n"\
        "\tOption:\n"\
        "\t-h show this help.\n"\
        "\t-i perform the installation, and you should use this option\n"\
        "\t   before using the backup to do something else.\n"\
        "\t-u perform the un-installation.\n"
}

help()
{
    echo -e "Command action\n"\
        "\th  show this help.\n"\
        "\ta  add any file that you want to backup to the database.\n"\
        "\td  delete any file that you no longer want from the database.\n"\
        "\tb  start backup.\n"\
        "\tbf assume \"yes\" as answer to all prompts and run non-interactively.\n"\
        "\tbb start backup but without incremental backup.\n"\
        "\tn  perform a trial backup with no changes made.\n"\
        "\tp  print the file record.\n"\
        "\tc  do some configurations, such as, modifying the path to the\n"\
        "\t   database or to the incremental backup directory.\n"\
        "\ts  show the current configuration.\n"\
        "\ti  perform the installation, and you should use this option\n"\
        "\t   before using the backup to do something else.\n"\
        "\tu  perform the un-installation.\n"\
        "\tq  quit"
}

color_echo()
{
    case "$1" in
        g)
            shift
            echo -e "\033[32m"$@"\033[0m"
        ;;
        gn)
            shift
            echo -e -n "\033[32m"$@"\033[0m"
        ;;
        r)
            shift
            echo -e "\033[31m"$@"\033[0m"
        ;;
        y)
            shift
            echo -e "\033[33m"$@"\033[0m"
        ;;
        yn)
            shift
            echo -e -n "\033[33m"$@"\033[0m"
        ;;
        *)
            shift
            echo $@
        ;;
    esac
}

XECHO()
{
    if [ "$XECHO" = 1 ]; then
        echo $@
    fi
}

check_src_dst()
{
    if ! test -e "$1" ||  ! test -e "$2"; then
        color_echo r "$1" or "$2" does not exist! ignore it!
        return 2
    fi

    local src_part1=`df "$1" | cut -d ' ' -f 1`
    local src_part2=`df "$2" | cut -d ' ' -f 1`
    local nsrc_inode=`ls -lid "$1" | cut -d ' ' -f 1`
    local ndst_inode=`ls -lid "$2" | cut -d ' ' -f 1`
    XECHO nsrc_inode:$nsrc_inode ndst_inode:$ndst_inode

    if [ "$src_part1" != "$src_part2" ]; then
        return 1
    fi

    if [ "$nsrc_inode" = "$ndst_inode" ]; then
            color_echo r "$src is equivalent to $dst. ignore it!"
            return 2
    fi

    if [ ! -e $db_pathname ]; then
        return 1
    fi

    while read -r tsrc tdst tex_src;
    do
        tsrc="${tsrc//@#@/ }"
        tdst="${tdst//@#@/ }"
        tex_src="${tex_src//@#@/ }"
        XECHO tsrc:"$tsrc" tdst:"$tdst"
        osrc_inode=`ls -lid "$tsrc" | cut -d ' ' -f 1`
        odst_inode=`ls -lid "$tdst" | cut -d ' ' -f 1`
        XECHO osrc_inode:$osrc_inode odst_inode:$odst_inode
        if [ "$nsrc_inode" = "$osrc_inode" -a "$ndst_inode" = "$odst_inode" ]; then
            if [ ${1:((${#1}-1))} = '/' -a ${tsrc:((${#tsrc}-1))} != '/' ] \
                || [ ${1:((${#1}-1))} != '/' -a ${tsrc:((${#tsrc}-1))} = '/' ]; then #/home and /home/ is very different!
                echo -n "";
            else
                return 0
            fi
        fi
    done < $db_pathname

    return 1
}

extract_src_dst()
{
    XECHO "extract src dst from $1"

    src="${1%#*}"
    dst="${1#$src}"
    dst="${dst#\#}"
    XECHO "src: $src"
    XECHO "dst: $dst"

    if [ "$src" = "" -o "$dst" = "" ]; then
        return 1
    else
        return 0
    fi
}

fix_path()
{
    local srcpath="$1"

    if [ "${srcpath:0:1}" = '/' ]; then
        echo $srcpath
    elif [ "${srcpath:0:2}" = './' ]; then
        echo `pwd`/${srcpath:2}
    else
        echo `pwd`/$srcpath
    fi
}

insert_new_item()
{
    XECHO add item src:"$1" dst:"$2" exclude:"$3"
    tmp1="${1// /@#@}"
    tmp2="${2// /@#@}"
    tmp3="${3// /@#@}"
    echo "$tmp1" "$tmp2" "$tmp3" >> $db_pathname
    return $?
}

parse_item()
{
    if ! extract_src_dst "$1"; then
        color_echo r "src:$src or dst:$dst is illegal!"
        return 1
    fi

    src=`fix_path "$src"`
    dst=`fix_path "$dst"`

    XECHO after fixed, src:"$src"
    XECHO after fixed, src:"$dst"

    return 0
}

do_add()
{
    local item

    color_echo g "Enter the mode of adding files! Some patterns are available, as follows:"
    color_echo g "eg: /home/#/tmp/ means we want to backup the whole things which "
    color_echo g "are under home directory to /tmp directory."
    color_echo g "eg: /home/#/tmp/:/etc/#/tmp/ means we want to backup the whole "
    color_echo g "things which are under the home directory and the /etc/ directory "
    color_echo g "to the /tmp directory, you can append any item with ':'."
    color_echo r "Note: /home and /home/ are quite different, because /home just means "
    color_echo r "/home itself while /home/ means the whole contents of /home."

    read -p "Please type in file items: " items
    items="`echo "$items" | sed "s/'//g"`"

    flag=0
    while [ $flag = 0 ];
    do
        item=${items%%:*}
        items=${items#$item:}
        ex_src=""
        if [ "$items" = "$item" ]; then
            flag=1
        fi
        if parse_item "$item"; then
            check_src_dst "$src" "$dst"
            ret=$?
            if [ "$ret" = 0 ]; then
                color_echo y "Warning! ""$src#$dst"" is already existed! do not re-submit!"
                continue
            elif [ "$ret" = 2 ]; then
                continue
            fi

            read -p "Would you like to add some excluding conditions to $src: (y/n)[n] " yn
            if [ "$yn" = y ]; then
                color_echo r "Note: this is an expert mode, and we don't check your pattern"
                color_echo r "is valid or not. Some patterns are available, as follows:"
                color_echo r "eg: if your src directory is /home, and your want to exclude"
                color_echo r "the directory /home/rongp, then you should type in \"rongp\"."
                color_echo r "eg: if your src directory is /home, and your want to exclude"
                color_echo r "the directory /home/rongp and /home/test, then you should"
                color_echo r "type in \"rongp:test\", and you can append any item with ':' ."

                read -p "Please type in paths to the excluding files: " exitem
                ex_src="$exitem"
            fi

            if insert_new_item "$src" "$dst" "$ex_src"; then
                echo ""$src"#"$dst" add successed!"
            else
                echo ""$src"#"$dst" add failed!"
            fi
        else
            read -p "skip it? Yy/Nn:[n] " yn
            if [ "$yn" = "y" -o "$yn" = "Y" ]; then
                continue
            fi
            return 1
        fi
    done

    return 0

}

get_choices()
{
    local total_line=`wc -l $db_pathname | cut -d ' ' -f 1`

    unset select_tab
    color_echo g "Enter the mode of "$1"! some patterns are available, as follows:"
    color_echo g "eg: 1-3 means select no 1 2 3 item"
    color_echo g "eg: 1:3:5 means select no 1 3 5 item"
    color_echo g "you can append any no with ':' or '-', but don't mix use it."
    color_echo g "no 0 means select all."
    do_print
    read -p "Please type in the number: " NO
    if [ "${NO/-/ }" != "$NO" ]; then
        num_tab=(${NO//-/ })
        [ ${#num_tab[@]} -gt 2 ] && \
            echo "Select failed, argument $NO is illegal!" && return 1

        num0=${num_tab[0]}
        num1=${num_tab[1]}
        XECHO num0:$num0 num1:$num1

        if [ -z "${num0//[0-9]/}" -a "$num0" -le "$total_line" -a "$num0" -gt "0" ]\
           && [ -z "${num1//[0-9]/}" -a "$num1" -le "$total_line" -a "$num1" -gt "0" ]\
           && [ "$num0" -lt "$num1" ];
        then
            select_tab=(`seq $num0 $num1`)
        else
            echo "Select failed, argument $NO is illegal!" && return 1
        fi
    elif [ "${NO/:/ }" != "$NO" ]; then
        for num in ${NO//:/ }
        do
            if [ -z "${num//[0-9]/}" ]&&[ "$num" -le "$total_line" ]\
                &&[ "$num" -gt "0" ]; then
                continue
            else
                echo "Select failed, argument $num is illegal!" && return 1
            fi
        done

        j=0
        for i in ${NO//:/ }
        do
            select_tab[j]=$i
            XECHO num:$i
            ((j++))
        done
    else
        if [ "$NO" = 0 ]; then
            XECHO num0:${NO}
            select_tab=(`seq 1 $total_line`)
        elif [ -z "${NO//[0-9]/}" ]&&[ "$NO" -le "$total_line" ]\
                &&[ "$NO" -gt "0" ]; then
            select_tab[0]=${NO}
            XECHO select_tab[0]:${NO}
        else
            echo "Select failed, argument $NO is illegal!" && return 1
        fi
    fi

    return 0
}

do_del()
{
    if ! get_choices "deleting files"; then
        return 1
    fi

    local total_num=${#select_tab[@]}

    if [ "$total_num" = 1 ]; then
        nums=${select_tab[0]}d
    elif [ "$total_num" = 2 ]; then
        nums=${select_tab[0]},${select_tab[1]}d
    else
        for ((i=0; i<$total_num; ++i))
        do
            nums+="${select_tab[i]}d;"
        done
    fi

    sed -i "$nums" $db_pathname >/dev/null 2>&1
    [ "$?" = 0 ] && echo "$NO delete successed!" || echo "$NO delete failed, delete failed!"
}

do_print()
{
    [ ! -s $db_pathname ] && color_echo y "Warning, no record found!" && return 1
    echo "     no     source     destination     action"
    cat -n $db_pathname | sed 's/@#@/ /g'
}

check_in_select_tab()
{
    local i

    for ((i=0; i<${#select_tab[@]}; ++i))
    do
        XECHO $1:select_tab[$i]:${select_tab[i]}
        if [ "${select_tab[i]}" = "$1" ]; then
            return 0
        fi
    done

    return 1
}

do_backup()
{
    local ex_file=`mktemp`
    local fake=
    local yes=
    #local wib="${1/without-incremental-backup/"--backup --backup-dir=$inc_path/$(date +%Y-%m-%d_%H:%M:%S_$(basename ${tmpsrc})_$(basename $tmpdst))"}"
    local wib

    [ ! -f "$db_pathname" ] && color_echo r "$db_pathname does not exist!" && return 1

    if ! get_choices "backup"; then
        return 1
    fi

    if [ "$1" = fake ]; then
        fake="-n"
    elif [ "$1" = yes ]; then
        yes=y
    fi

    local i=0
    local k=0
    while read -r src dst ex_src;
    do
        if check_in_select_tab $((i+1)); then
            XECHO "$i in select table"
            src="${src//@#@/ }"
            dst="${dst//@#@/ }"
            XECHO src:$src dst:$dst ex_src:$ex_src ex_file:$ex_file
            src_tab[k]="$src"
            dst_tab[k]="$dst"
            ex_src_tab[k]="$ex_src"
            ((k++))
        fi
        ((i++))
    done < $db_pathname

    for ((j=0; j<$k; ++j))
    do
        echo src:${src_tab[j]} dst:${dst_tab[j]} ex_src:${ex_src_tab[j]}
        src="${src_tab[j]}"
        dst="${dst_tab[j]}"
        ex_src="${ex_src_tab[j]}"
        echo "$ex_src" | awk -F ':' '{for (i=1;i<=NF;++i)print $i}' | sed 's/@#@/ /g' > $ex_file

        if [ "$src" = "/" ]; then
            tmpsrc=$(blkid `mount | grep "/ " | cut -d ' ' -f 1`  | awk -F "\"" '{print $2}')
        else
            tmpsrc="$src"
        fi

        if [ "$dst" = "/" ]; then
            tmpdst=$(blkid `mount | grep "/ " | cut -d ' ' -f 1`  | awk -F "\"" '{print $2}')
        else
            tmpdst="$dst"
        fi

        if [ "$1" = "wib" ]; then
            wib=
        else
            wib="--backup --backup-dir=$inc_path/$(date +%Y-%m-%d_%H:%M:%S_$(basename ${tmpsrc})_$(basename $tmpdst))"
        fi

        color_echo g "We will start backup from "
        color_echo r "$src"
        color_echo g to
        color_echo r "$dst"
        color_echo g "with excluding file or directory"
        color_echo r "${ex_src//@#@/ }"
        color_echo gn "continue or not? y/n: "

        if [ "$yes" = y ]; then
            yn=y
        else
            read yn
        fi
        if [ "$yn" = y ]; then
            echo Start backup "$src" to "$dst" with excluding file or directory "$ex_src"
            (
            flock -x 200

            echo rsync -aAXvzrtopg $fake --progress --delete --exclude-from=$ex_file \
                "$src" "$dst" "$wib"
            eval rsync -aAXvzrtopg $fake --progress --delete --exclude-from=$ex_file \
                "$src" "$dst" "$wib"
            ) 200>/var/lock/abc

            echo Backup $src to $dst with excluding file or directory $ex_src finished!
        else
            echo Skip backup $src to $dst with excluding file or directory $ex_src!
        fi
    done

}

get_answer()
{
    local ret

    if [ "$4" != "" ]; then
        tmpbackup="$4"
    else
        tmpbackup=backup.cfg.bak
    fi

    while :
    do
        read -p "Type in $1 path of the backup(default is $2, q for exit): " ans_tmp
        if [ "$ans_tmp" = q ]; then
            ret=1
            break
        elif [ "$ans_tmp" != "" ]; then
            if [ ! -d "$ans_tmp" ]; then
                echo "$1: $ans_tmp is invalid!"
                read -p "Would you like to create it now? y/n [y]: " yn
                if [ "$yn" = y ]; then
                    mkdir -p $ans_tmp
                else
                    continue
                fi
            fi

            sed -i "s,$3.*,$3$ans_tmp,g" $tmpbackup
            ret=$?
            break
        else
            ans_tmp="$2"
            ret=0
            break
        fi
    done

    return $ret
}

already_install()
{
    if load_cfg $backup_cfg s; then
        XECHO "already install"
        return 0 #has install
    fi

    return 1
}

do_install()
{
    color_echo g start install
    if already_install; then
        color_echo y  "We check that you have already installed, you should"
        color_echo yn "uninstall first, would you want to uninstall it first?y/n[n] "
        read yn
        if [ "$yn" != y ]; then
            color_echo g install finished!
            color_echo r install failed!
            return 1
        else
            do_uninstall
        fi
    fi

    cp -f backup.cfg backup.cfg.bak
    load_cfg backup.cfg.bak s
    if [ "$?" = 1 ]; then
        exit
    fi

    if ! get_answer "executable file backup" "$bin_path" "INSTALL_PATH=";then
        color_echo g install finished!
        color_echo r install failed!
        return 1
    fi
    install_path=$ans_tmp
    color_echo g install path is $install_path

    if ! get_answer "database" "$db_path" "DB_PATH=";then
        color_echo g install finished!
        color_echo r install failed!
        return 1
    fi
    db_path=$ans_tmp
    color_echo g database path is $db_path

    if ! get_answer "incremental backup" "$inc_path" "INCREMENTAL_BACKUP_PATH=";then
        color_echo g install finished!
        color_echo r install failed!
        return 1
    fi
    inc_path=$ans_tmp
    color_echo g incremental backup path is $inc_path

    echo
    who=`whoami`
    cp backup $install_path
    color_echo g install backup to $install_path
    ret=$?
    mv backup.cfg.bak $backup_cfg
    color_echo g install $backup_cfg
    ret=$((ret+$?))
    mkdir -p $db_path
    color_echo g install $db_path
    ret=$((ret+$?))
    mkdir -p $inc_path
    color_echo g install $inc_path
    ret=$((ret+$?))
    ln -s $db_path $inc_path/db
    color_echo g install $inc_path/db
    ret=$((ret+$?))
    color_echo g install finished!
    if [ $ret -gt 0 ]; then
        color_echo r install failed!
        [ -e $bin_path/backup ] && rm_print $bin_path/backup
        [ -e $backup_cfg ] && rm_print $backup_cfg
        [ -e $inc_path/db ] && rm_print $inc_path/db && rm_print -rf $inc_path
        [ -e $db_pathname ] && rm_print $db_pathname
        rm_print -d $db_path
        return 1
    fi

    echo
    echo
    color_echo y "The installation work is done, and you can remove this package now!"
    color_echo y "Note: you should put the executable file \"backup\""
    color_echo y "into \$PATH and you need to get \"root\" privileges to execute it."
    color_echo y "for example, you can execute it like this in ubuntu: sudo backup"
    return 0
}

rm_print()
{
    color_echo g remove $@
    eval rm $@
}

do_uninstall()
{
    XECHO "Perform the un-installation."
    color_echo g perform the un-installation...
    if ! load_cfg $backup_cfg; then
        color_echo g uninstall failed!
    fi
    [ -e $bin_path/backup ] && rm_print $bin_path/backup
    [ -e $backup_cfg ] && rm_print $backup_cfg
    [ -e $inc_path/db ] && rm_print $inc_path/db && rm_print -rf $inc_path
    [ -e $db_pathname ] && rm_print $db_pathname
    rm_print -d $db_path
    color_echo g uninstall finished!
    color_echo g uninstall ok!
}

load_cfg()
{
    if [ ! -e "$1" ]; then
        [ "$2" != "s" ] && color_echo r "Error, we can't find the configure file $1, exit now!"
        return 1
    fi

    bin_path=`sed -n 's/INSTALL_PATH=\(.*\)/\1/p' $1`
    db_path=`sed -n 's/DB_PATH=\(.*\)/\1/p' $1`
    db_pathname=$db_path/backup.db
    inc_path=`sed -n 's/INCREMENTAL_BACKUP_PATH=\(.*\)/\1/p' $1`

    if [ ! -d "$inc_path" ]; then
        [ "$2" != "s" ] && color_echo r Load configuration file failed! your should
        [ "$2" != "s" ] && color_echo r check the directory $db_pathname is valid or not!
        return 2
    fi

    XECHO database path is $db_path
    XECHO database file path is $db_pathname
    XECHO incremental backup path is $inc_path
    return 0
}

show_configure()
{
    color_echo g executable backup is in $bin_path
    color_echo g database directory is in $db_path
    color_echo g incremental backup directory is in $inc_path
}

do_modify_inc_backup_path()
{
    if ! get_answer "incremental backup" "$inc_path" \
        "INCREMENTAL_BACKUP_PATH=" $backup_cfg;then
        return 1
    fi

    inc_path=$ans_tmp
    XECHO incremental backup is $inc_path
    return 0
}

do_configure()
{
    color_echo g [1] modify incremental backup path
    color_echo g [2] ...
    read -p "Please type in the no which you are expecting to: " no

    if [ "$no" = 1 ]; then
        do_modify_inc_backup_path
    else
        color_echo r Unsupported operator!
    fi
}

backup_start()
{
    if ! load_cfg $backup_cfg; then
        exit
    fi

    while :
    do
        read -p "Command (h for help): " cmd
        case "$cmd" in
            a)
                do_add
                ;;
            d)
                do_del
                ;;
            p)
                do_print
                ;;
            c)
                do_configure
                ;;
            b)
                do_backup
                ;;
            bf)
                do_backup yes
                ;;
            bb)
                do_backup wib
                ;;
            n)
                do_backup fake
                ;;
            s)
                show_configure
                ;;
            i)
                do_install
                ;;
            u)
                do_uninstall
                exit
                ;;
            q)
                break
                ;;
            h | *)
                help
                ;;
        esac
    done
}

username=`echo $USER`

if [ "$username" != root ]; then
    color_echo r "Error, you need to have \"root\" privileges to execute this program."
    exit
fi

if [ "$1" = "-i" ]; then
    if ! do_install; then
        color_echo y "Sorry, We can't continue any more. Exit now!"
    fi
    exit
elif [ "$1" = "-u" ]; then
    do_uninstall
    exit
elif [ "$1" = "-h" ]; then
    _help
    exit
fi

if [ ! -e $backup_cfg ]; then
    color_echo r "$backup_cfg does not exist! "
    read -p "You need to install the backup first. perform the installation? y/n?[y]: " yn
    if [ "$yn" != n ]; then
        do_install
    else
        echo Sorry, we can\'t continue any more. Exit now!
    fi
    exit
fi

backup_start

下面是默认配置backup.cfg

#############################
######
#############################
AUTHOR=rongp
EMAIL=rongpmcu@gmail.com
VERSION=1.0

INSTALL_PATH=/usr/bin/
DB_PATH=/var/lib/backup/
INCREMENTAL_BACKUP_PATH=/var/lib/backup/incr_backup

基本操作流程演示

  1. 下载backup和backup.cfg,给backup添加可执行权限
  2. 从usb起linux系统(推荐ubuntu)
  3. 挂载所有要备份的源和目的磁盘的分区
  4. 执行sudo ./backup -i进行安装,安装过程设置好这次备份相关的配置文件路径,可以将路径设置到永久存储的分区,这样下次可以直接使用
  5. 执行sudo backup进入备份程序,操作界面和fdisk类似,h调出帮助界面,先执行a添加要备份的条目,在备份的过程中,可以添加过滤的文件或者目录
  6. 执行bf进入正式的备份,也可以先执行n来模拟备份,执行bb的话,会只备份,而不保留之前的文件(bf会自动保存覆盖的文件,用于以后的恢复)

总结

  该脚本一直作为我个人备份的工具,从ubuntu到arch,完全满足了我的需求,希望对其他人也有用,也希望大家多提意见^_^

引用

完!
2012年6月

转载于:https://www.cnblogs.com/rongpmcu/p/7662158.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值