Linux回收站

作者: neilzwshen | 来源:发表于2019-03-05 11:20 被阅读2次
    • 我们在Linux环境中工作时, 经常会用到rm命令删除文件, 但是rm命令是即刻删除的, 有时可能会出现误删的问题.
    • 针对这种情况, 本文参考网上已有解决方案, 学习并编写了一个回收站脚本.

    一 工具

    • 基本功能
      1. 暂存被删除文件 rm <file/directory>
      2. 恢复被删除文件 re <file/directory>
      3. 清空回收站 rc
      4. 获取回收站大小 rsize

    初始化与安装

    1. github, https://github.com/trioZwShen/itrashcan.git
    2. ~/.bashrc中粘贴下面的设置环境变量, 并执行source ~/.bashrc, 或者重新打开终端
      # itrashcan
      export itrashcan="/home/szw/repos/itrashcan" # set the script path
      export itrashcan_home="/home/szw/.trashcan" # set the transcan path
      source "$itrashcan/config.sh" # source the config for alias
      
    3. 初始化itrashcan
      bash $itrashcan/init.sh
      
    4. 查看config.sh中的命令别名
      # set alias
      # rm by itrashcan
      alias rm="$itrashcan/delete.sh"
      # clear the trashcan
      alias rc="$itrashcan/clear.sh"
      # restore the target
      alias re="$itrashcan/restore.sh"
      # go to the trashcan
      alias gor="cd $itrashcan_home/trash"
      # get the size of trashcan
      alias rsize="du -sh $itrashcan_home/trash"
      
    5. 删除回收站
      • bash remove.sh

    测试

    • rm
    $ ls
    a  b  c
    $ rm *
    /home/szw/download/a is move to trashcan
    /home/szw/download/b is move to trashcan
    /home/szw/download/c is move to trashcan
    
    • re
    $ re a b
    /home/szw/download/a restored
    /home/szw/download/b restored
    
    • rc
    $ rc
    Are you sure you want to permanently erase the items in the Trash?[Y/n]
    Y
    Done!
    
    • rsize
    $ rsize
    4.0K    /home/szw/.trashcan/trash
    


    二 功能实现

    1 环境初始化

    环境变量

    # itrashcan
    export itrashcan="/home/szw/repos/itrashcan" # set the script path
    export itrashcan_home="/home/szw/.trashcan" # set the transcan path
    source "$itrashcan/config.sh" # source the config for alias
    
    • itrashcan设置为脚本所在路径
    • itrashcan_home设置为回收站的目标位置, 回收站名称可以自拟
    • config.sh中包含了itrashcan的命令别名

    脚本

    • init.sh 执行前需设置环境变量
      1. 检查环境变量是否被设置
      2. 检查回收站目标位置是否有冲突
      3. 创建回收站
      4. 初始化脚本以及回收站的权限
    #!/bin/bash
    # run this script for init your environment
    # set -x
    set -e
    
    # check the $itrashcan_home.
    if [ ! -n "$itrashcan_home" ]; then
        echo "Please set the environment var first!!!"
        exit
    fi
    
    # exit if the $itrashcan_home already exists.
    if [ -d "$itrashcan_home" ]; then
        echo "The directory already exists in the target path, please check!!!"
        exit
    fi
    
    # create trashcan and trash log
    mkdir $itrashcan_home
    mkdir $itrashcan_home"/trash"
    touch $itrashcan_home"/trash.log"
    
    # init permissions
    chmod 777 -R $itrashcan_home
    chmod 755 -R $itrashcan
    
    echo "Init Done."
    
    • remove.sh
      • 删除回收站
    #!/bash/bin
    # run this script for remove itrashcan config and environmental
    # set -x
    set -e
    # clear file and directory
    /bin/rm -rf $itrashcan_home
    echo "Remove done."
    

    2 删除文件

    delete.sh

    1. 该脚本首先会检查环境是否已经初始化, 没有则init
      # init if the $itrashcan_home not exists
      if [ ! -d "$itrashcan_home" ]; then
          bash init.sh
      fi
      
    2. 检查输入是否正确, 如果-f选项, 那么使用real rm
    3. 利用lldu判断目标文件是否大于2G, 如果大于2G, 则会直接删除
    4. 重命名回收站中的文件为filename_deletetime, 防止文件重名
    5. 获取文件的绝对路径, 用于恢复回收站文件
    6. 移动文件, 并打log
    #!/bin/bash
    # set -x
    set -e
    realrm="/bin/rm"
    
    # init if the $itrashcan_home not exists
    if [ ! -d "$itrashcan_home" ]; then
        bash init.sh
    fi
    
    # usage tips
    if [ $# -eq 0 ]; then
        echo "Usage:delete file [file2 file3 ...]"
        echo "If the options contain -f then the script will exec 'rm' directly."
    fi
    
    # identify input options, if f is point then exec realrm
    while getopts "dfiPRrvw" opt
    do
        case $opt in
        f)
            echo "real rm done"
            exec $realrm "$@"
            ;;
        d)
            # do nothing
            ;;
        i)
            # do nothing
            ;;
        P)
            # do nothing
            ;;
        R)
            # do nothing
            ;;
        r)
            # do nothing
            ;;
        v)
            # do nothing
            ;;
        w)
            # do nothing
            ;;
        ?) # unknow argument
            exit
            ;;
        esac
    done
    
    # travel the input file
    for file in $@
    do
        if [ -f "$file" -o -d "$file" ]; then
            # real rm if size is larger than 2G
            if [ -f "$file" ] && [ `ls -l $file|awk '{print $5}'` -gt 2147483648 ]
            then
                echo "$file size is lager than 2G, will be deleted directly"
                rm -rf $file
            fi
            if [ -d "$file" ] && [ `du -sb $file|awk '{print $1}'` -gt 2147483648 ]
            then
                echo "The directory: $file size is lager than 2G, will be deleted directly"
                rm -rf $file
            fi
    
            # rename
            now=`date +%Y-%m-%d_%H_%M_%S`
            filename=`basename $file`
            newfilename="${filename}_${now}"
    
            # get fullpath
            basepath=$(cd `dirname $file`; pwd)
            fullpath="${basepath}/${filename}"
    
            # mv to trashcan
            if mv -f "$fullpath" "$itrashcan_home/trash/$newfilename"
            then
                bash $itrashcan/log.sh $newfilename $filename $now $fullpath
                echo "$fullpath is move to trashcan"
            else
                echo "fail"
            fi
    
        else
            echo "$file is not exist"
        fi
    done
    
    # trashcan size > 10G remider user
    if [ `du -sb "${itrashcan_home}"/trash|awk '{print $1}'` -gt 5368709120 ]; then
        echo "Warning: trashcan's size[`du -sh "${itrashcan_home}/trash"|awk '{print $1}'`] is biger than 5G."
    fi
    

    3 恢复数据

    restore.sh

    1. 检查输入
    2. 设置log路径, 回收站路径, 以及待查找的目标模式findpattern
    3. 在log中查找目标文件, 获取同名文件数rowcount;
      • 如果有多个重名文件, 需要用户自己确定恢复哪个
    4. 检查回收站中该文件是否存在
    5. 检查原路径是否存在, 检查原路径中是否有重名文件
    6. 恢复数据, 并删除该记录
    #!/bin/bash
    set -e
    if [ $# -eq 0 ]; then
        echo "Please enther the target what your want to restore!";
        exit;
    fi
    
    # travel the input file
    for target in $@
    do
        log="${itrashcan_home}/trash.log"
        trashcan="${itrashcan_home}/trash"
        findpattern="filename:${target};"
    
        # get the number of files with the same name
        rowcount=`cat -n "$log" | grep "$findpattern" | wc -l`
    
        if [ $rowcount -eq 0 ]; then
            echo "${target} does not exists in LOG"
            exit
    
        elif [ $rowcount -eq 1 ]; then
            output=`cat -n "$log" | grep "$findpattern"`
            index=`echo $output | awk '{print $1}'`
    
        else
            cat -n "${itrashcan_home}/trash.log" | grep "${findpattern}"
            echo -n "Please enter the line number of the target: "
            read index
            output=`cat -n "$log" | grep "\ ${index}\ *.*${findpattern}.*"`
        fi
    
        # get the fullpath and trashname by index
        fullpath=`echo $output | awk '{print $5}'`
        fullpath=${fullpath#*:}
        trashname=`echo $output | awk '{print $2}'`
        trashname=${trashname#*:}
    
        # check the trashname
        trashnamepath="${trashcan}/${trashname}"
        if [ ! -d "$trashnamepath" -a ! -f "$trashnamepath" ]; then
            echo "${target} does not exists in TRASHCAN"
            exit
        fi
        # Whether the original path exists.
        basepath=`dirname $fullpath`
        if [ ! -d $basepath ]; then
            echo "The original path [${basepath}] does not exist!!!"
            exit
        fi
        # Is there a duplicate file under the original path?
        if [ -d $fullpath -o -f $fullpath ]; then
            echo "The original path has a duplicate file [$fullpath]!!!"
            exit
        fi
    
        # restore from trashcan
        if ! mv -f "$trashnamepath" "$fullpath"; then
            echo "failed"
            exit
        else
            # delete the log
            sed -i "${index}d" $log
            echo "${fullpath} restored"
        fi
    done
    

    4 log

    log.sh

    • 需记录原文件名, 重命名后的文件名, 源文件所在路径
    #!/bin/bash
    log="${itrashcan_home}/trash.log"
    # create log file if log does not exist
    if [ ! -d $log ]; then
        touch $log
    fi
    echo "trashname:$1 filename:$2; deletetime:$3 fullpath:$4" >> $log
    

    5 清空回收站

    clear.sh

    #!/bin/bash
    echo "Are you sure you want to permanently erase the items in the Trash?[Y/n]"
    read ask
    if [ $ask = 'y' -o $ask = 'Y' ]
    then
        `rm -rf $itrashcan_home/trash/*`
        `rm -rf $itrashcan_home/trash.log`
        echo "Done!"
    fi
    

    参考blog
    https://www.jianshu.com/writer#/notebooks/27796113/notes/42433921/preview

    相关文章

      网友评论

        本文标题:Linux回收站

        本文链接:https://www.haomeiwen.com/subject/oxrnuqtx.html