Linux bash回收站

之前刚把组里服务器重新弄好的时候,受师兄启发想写个回收站,虽然shell script基本不会,但是搞了一两天还是怼出来了一个,然后过了几个月,现在基本看不懂当时写的啥了 😛

刚传上 https://github.com/nizekai/recyclebin

思路也挺简单的,就是用alias把真正的rm覆盖,然后每次删除就把文件移到$HOME/.trash/,做好日期和路径记录,然后恢复的时候就让用户选择文件恢复。如果参数里带了-f就转而用会真正的rm删除,测试效果挺好的。

省事的就丢/etc/profil.d/里,然后重新source或登录,rcyclbin enable 开启,recyclbin disable 关闭,默认开启可以写进~/.bashrc 或者 /etc/profile

例子:

[nzk@xxxx ~]$ touch testa testb
[nzk@xxxx ~]$ rm testa testb
Are you sure to delete the files to recyclebin?[y/n]y
testa      delete to rcycbin
testb      delete to rcycbin
[nzk@xxxx ~]$ rr -l
---List for recycle bin---
1:      testa from /home/nzk  as testa_2018-12-14_20:48:45
2:      testb from /home/nzk  as testb_2018-12-14_20:48:45
[nzk@xxxx ~]$ rr 1
Are u sure to recovery testa to /home/nzk?[y/n]y
testa has been resotred to /home/nzk
[nzk@xxxx ~]$

Code

# PROGRAM:
#   recycle bin   
# Usage: 
#   Use "rcyclbin enable" to enable this function, it will cover the "rm" command.
#       "rcyclbin disable" to disable this of course.
#   It will make a new dir ".trash" in $HOME dir for each user, storing every file that deleted by "rm" command.
#   Use "cleartrash"  to clear the recycle bin.
#   Use "rl"          to list for recycle bin.
#   Use "rr filename" to recovery file.
# History: 
#   2018/08/30  nzk     First release
# to be improved
realrm="/bin/rm"
del () {
    usage () {
        echo "Usage: rm [-fh] file1 [file2 ...]"
        echo "          -h for usage"
        echo "          If '-f' used, then the script will exec "
        echo "          real 'rm' command with full command directly"
        echo "       rr -l to see file in recyclebin"
    }
    local confirm currentTime filename filepath key
    local optflag=0
    if [[ "$#" -eq 0 ]]; then
        usage
        optflag=1
    fi
    if [[ "$1" =~ ^-.*f.*$ ]]; then
        optflag=1
        $($realrm "$@")
    fi
    if [[ "$1" == "-h" || "$1" == "--help" ]]; then
        optflag=1
        usage
    fi
    if [[ "$optflag" -eq 0 ]]; then
        read -p "Are you sure to delete the files to recyclebin?[y/n]" confirm
        if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then 
            if [[ ! -d "$HOME/.trash/" ]]; then
                mkdir ~/.trash
            fi
            if [[ -n "$*" ]]; then
                for file in "$@"; do
                    if [[ -e "$file" ]]; then
                        currentTime=`date +%Y-%m-%d_%H:%M:%S`
                        filename="${file##*/}_${currentTime}"
                        [ -d "$file" ] && filename="$filename/" && file="$file/"
                        filepath=$(cd "$(dirname "$(pwd)/$1")";pwd)
                        if mv -f $file $HOME/.trash/$filename ; then
                            [ ! -e "$HOME/.trash/.log" ] && touch ~/.trash/.log
                            printf "%-20s %-20s %-40s\n" $file $filepath $filename >> ~/.trash/.log
                            printf "%-10s delete to recyclebin\n" $file
                        fi 
                    fi
                done
            fi
        fi
    fi
    unset -f usage
}

recoveryfile () {
    usage () {
        echo "Usage:     -h for help"
        echo "           -l to list record in recyclebin"
        echo "           append file number that listed to recovery"
    }
    list () {
        if [[ $# -eq 0 ]]; then
            echo "---List for recycle bin---"
            [ -e "$HOME/.trash/.log" ] && awk '{printf "%d: %10s from %-10s as %-20s\n",NR,$1,$2,$3}' ~/.trash/.log 
        else
            echo "Hell is empty"
        fi
    }
    if [[ $# -eq 0 ]]; then
        usage
    fi
    local key
    local optflag=0
    if [[ "$*" =~ ^-.*$ ]]; then
        optflag=1
        while [[ $# -gt 0 ]]; do
            key="$1"
            case $key in
                -h)
                    usage
                    shift
                    ;;
                -l)
                    shift
                    list $@
                    shift
                    ;;
                *)
                    shift
            esac
        done
    fi
    if [[ "$optflag" -eq 0 && "$1" =~ ^[0-9]+$  ]]; then
        local file filepath filename ck
        file=$(awk 'NR==n {print $1}' n=$1 $TRASHLOG)
        filepath=$(awk 'NR==n {print $2}' n=$1 $TRASHLOG)
        filename=$(awk 'NR==n {print $3}' n=$1 $TRASHLOG)
        read -p "Are u sure to recovery $file to $filepath?[y/n]" ck
        if [[ "$ck" == 'y' || "$ck" == 'Y' ]]; then
            $(mv -i $TRASHDIR/$filename $filepath/$file) && echo "$file has been resotred to $filepath" && `sed -i "$1"d $TRASHLOG` 
        fi
    fi 
    unset -f usage
    unset -f list
}

cleartrash () {
    local confirm
    read -p "r u sure to clear the trash bin?[y/n]" confirm
    [ "$confirm" == 'y' ] || [ "$confirm" == 'Y' ] && /bin/rm -rf $TRASHDIR && mkdir $TRASHDIR && touch $TRASHLOG
}

rcyclbin () {
    usage () {
        echo -e "Usage : ryclbin enable|disable|clear"
    }
    if [[ -n "$1" ]]; then
        if [[ "$1" == "enable" ]]; then
            alias rm=del
            alias rl='ls ~/.trash'
            alias rr=recoveryfile
            export TRASHDIR=$HOME/.trash
            export TRASHLOG=$TRASHDIR/.log
        elif [[ "$1" == "disable" ]]; then
            unalias rm
            unalias rl
            unalias rr
            export TRASHBIN=
            export TRASHLOG=
        elif [[ "$1" == "clear" ]]; then
            cleartrash
        else
            usage
        fi
    else
        usage
    fi
    unset -f usage
}

发表评论

电子邮件地址不会被公开。