可恢復的安全rm

我們經常使用rm去刪除一些文件,如果不小手一抖,那麼就悲劇了,你們都懂的。。。

在經歷過一次這樣的慘劇後,決定永遠杜絕這種情況,重寫寫了shell函數,執行安全的rm。這個函數會把要刪除的文件按日期備份到指定的目錄,同時根據刪除時間的不同會有多個版本,同時提供了另外一個函數用於恢復之前刪除的文件。

# safe rm
# Don't remove the file, just move them to a temporary directory.
# Files are grouped by remove time.
# e.g.
#   # pwd => /home/work/
#   > rm -r -f aa
#   'aa' will move to ~/.TrashHistory/20141018/aa@120111@_home_work_aa
_RM_BACKUP_PATH=/Users/louzhenlin/.TrashHistory
function safe_rm() {
    # skip cmd option, e.g. '-rf' in 'rm -rf a b' or '-r/-f' in 'rm -r -f a b'
    local first_char=${1:0:1}
    until [ ! "$first_char" = "-" ]
    do
        shift
        first_char=${1:0:1}
    done

    # check param
    if [ $# -lt 1 ]; then
        echo 'usage: rm [-f | -i] [-dPRrvW] file ...'
        exit 1
    fi

    local today=`date +"%Y%m%d"`
    local mvpath=${_RM_BACKUP_PATH}/$today

    # support for multi version
    local timestamp=`date +"%H%M%S"`

    # create dir if path non-exist
    if [ ! -d $mvpath ]; then
        mkdir $mvpath
    fi

    until [ $# -eq 0 ]
    do
        # fetch absolute path of the file
        local file_path=$1
        local fchar=`echo "${file_path:0:1}"`
        if [ "$fchar" = "/" ]; then
            local dist_path="_${file_path}"
        else
            local abs_fpath=`pwd`/$file_path
            local dist_path="${file_path}@${timestamp}@${abs_fpath}"
        fi

        # substitue '/' to '_'
        local final_dist_path=${dist_path//\//^}

        # mv to temp trash
        mv $file_path $mvpath/$final_dist_path

        # next file
        shift
    done
}


上面是safe_rm函數,在備份目錄下顯示:

➜  ~  ll ~/.TrashHistory/20141021
total 32
drwxr-xr-x  7 louzhenlin  staff  238 10 21 18:01 .
drwxr-xr-x  5 louzhenlin  staff  170 10 21 15:51 ..
-rw-r--r--  1 louzhenlin  staff  136 10 20 23:39 a@180117@^Users^louzhenlin^dev^workspace^c_cpp^leveldb^a
-rw-r--r--  1 louzhenlin  staff  399 10 14 17:43 aof.log@164609@^Users^louzhenlin^dev^workspace^python^redis^aof^modifer^aof.log
-rw-r--r--  1 louzhenlin  staff    0 10 14 11:19 appendonly-1.aof@155727@^Users^louzhenlin^dev^server^redis-2.8.17^appendonly-1.aof
-rw-r--r--  1 louzhenlin  staff  399 10 14 17:42 appendonly.aof@155105@^Users^louzhenlin^dev^server^redis-2.8.17^appendonly.aof
-rw-r--r--  1 louzhenlin  staff  565 10 21 15:56 appendonly.aof@161315@^Users^louzhenlin^dev^server^redis-2.8.17^appendonly.aof

可以看到,文件中包含時間以及全路徑信息,以便用於恢復。下面是用於恢復的函數:

# revert files that remove by safe_rm
# you can choose the right one in multi files removed
function revert_rm() {
    # process multi files
    until [ $# -eq 0 ]
    do
        echo "revert for $1:"
        for _f in `find $_RM_BACKUP_PATH -name "$1@*" -print`
        do
            local d=`echo $_f | awk -F\/ '{print $2}'`
            local t=`echo $_f | awk -F@ '{print $2}'`
            local file_path=`echo $_f | awk -F@ '{print $3}'`
            file_path=${file_path//^/\/}

            echo -n "      $file_path at ${d:0:4}-${d:4:2}-${d:6:2} ${t:0:2}:${t:2:2}:${t:4:2}   [y/n]? "
            read _confirm
            if [ "${_confirm}" = 'y' ]; then
                mv $_f $file_path
                break
            fi
        done

        shift
    done
}

revert_rm會將多個版本的文件列出來,用於選擇想要恢復的那個。

➜  ~  revert_rm appendonly.aof
revert for appendonly.aof:
      /Users/louzhenlin/dev/server/redis-2.8.17/appendonly.aof at 2014-10-21 15:51:05   [y/n]? n
      /Users/louzhenlin/dev/server/redis-2.8.17/appendonly.aof at 2014-10-21 16:13:15   [y/n]? y
使用時,可以建立一個alias將rm指向safe_rm即可。希望大家用的開心哈。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章