功能描述:

我们都知道linux不同于windows的一点是Windows有回收站机制,这样如果我们想将之前删掉的一个文件还原直接到回收站里就可以实现,这给了我们一次反悔的机会。所以我考虑在我的linux上也加入这个功能,来防止“rm -rf”造成的误删除导致数据丢失。

我现在通过脚本来实现这个回收站机制。rm脚本实现的是删除,替换了原系统中的rm,将删除的文件都回收到了用户家目录下的一个叫./recycle的目录里了,到时只要在这个目录里找回就可以啦,注意rm删除的东西都被真的删除,就有个问题啦:回收站的东西无法删除,解决这个问题就要有另一个脚本啦,清空回收站的脚本,用recycle来实现。

1.rm删除文件和文件夹,用法与自带rm命令相似2.recycle显示回收站里面的内容:可以按名字排序,也可以按删除时间排序。   recycle -d可以进入整理回收站的模式: 用法举例如下           recycle -d -empty清空回收站                                 recycle -d -t 3清空3天前的文件                                  recycle -d -s 5清空超过5M的文件                                  recycle -d -t 3 -s 5清空3天前且大小超过5M的文件           $ rm --helpUsage: rm [-r] [-f]  [file]...del file and move it the recycle与系统自带的rm命令参数一致复制代码$ recycle --helprecycle version 1.0Usage: recycle [-l] [-n] [-r]       recycle -d -empty       recycle -d [-f] [-t 

如果要定期清空回收站的话,就添加一个计划任务。

环境描述:

现在我有不止一台的linux系统,如果一台一台的scp脚本会很麻烦,我选择使用salt来进行推送脚本,及设置计划任务来清空回收站。每台linux机器上基本都有root和dev两个用户,salt设置的只能root用户来使用,这样就没办法通过salt推送recycle命令来清空dev用户的回收站了,我在这儿采取的一个方法是:mv /home/dev/.recycle/* /root/.recycle/下做一下中转就可以通过salt来清空dev的回收站了。还有个问题如果服务器的硬盘比较小,如果某次删除的东西特别大,就会硬盘报警,我们可以写个脚本并设置计划任务来判断它的使用空间大于多少时就会清空回收站,配合定期清空回收站来使用,这个脚本叫recycle.sh。

推送脚本并赋予执行权限:

salt '*' cp.get_file salt://files/rm /usr/local/bin/rmsalt '*' cp.get_file salt://files/recycle /usr/local/bin/recyclesalt '*' cp.get_file salt://files/recycle.sh /usr/local/bin/recycle.shsalt '*' cmd.run 'chmod +x /usr/local/bin/rm'salt '*' cmd.run 'chmod +x /usr/local/bin/recycle'salt '*' cmd.run 'chmod +x /usr/local/bin/recycle.sh'

在salt服务器上设置计划任务:

crontab -l* 5 */3 * * /usr/bin/salt '*' cmd.run '/usr/local/bin/recycle -d -empty' &> /dev/null* 1 */3 * * /usr/bin/salt '*' cmd.run '/bin/mv /home/dev/.recycle/* /root/.recycle/' &> /dev/null* */1 * * * /usr/bin/salt '*' cmd.run '/usr/local/bin/recycle.sh' &> /dev/null

rm脚本:

### =============================================# Version    : 1.1# Date       : 20090506# Author     : devinwang# Changes    : what is new[ -d ~/.recycle ] || mkdir ~/.recycleRECYCLE_DIR=~/.recycleVERSION=1.0function echo.log {        local line_no=${BASH_LINENO[0]}        local file_name=$0                echo "${file_name}:${line_no}:$@"}echo.ok() {        if [[ $1 == "-n" ]]; then                shift                echo -n -e"\\033[1;32m$@\e[0m"        else                echo -e"\\033[1;32m$@\e[0m"        fi}echo.err() {        if [[ $1 == "-n" ]]; then                shift                echo -n -e"\\033[1;31m$@\e[0m"        else                echo -e"\\033[1;31m$@\e[0m"        fi}function yesOrNo {    local answer=""    local ret=0    local message="$@, (Y)es/(N)o? [n] "    : ${REDIRECT:=/dev/tty}    while true ; do                read -p"${message}" answer < $REDIRECT > $REDIRECT 2>&1                case"$answer" in                       [yY]) ret=0; break ;;                       [nN]|"")         ret=1; break ;;                       *)       echo; continue                esac    done    return $ret}mvToRecycle() {        ### file OR dir not exist        if [[ ! -a "$1" ]]; then                echo.err rm: cannotremove \`$1\': No such file or directory                return 1        fi        if [[ -d "$1" ]]; then                t="directory"                st="d"        else                t="file"                st="f"        fi        ### dir        if [[ -d "$1" &&"$option" != *r* ]]; then                echo.err rm: cannotremove \`$1\'\: Is a directory                return 1        fi        ### prompt        if [[ $option != *f* ]]; then                ### if type no, return                yesOrNo "remove $t\`$1'" \                || return 0        fi        ### remove dir        mv  -- "$1""${RECYCLE_DIR}/${DATE}_${st}_${1}"  \                       && echo.ok removed $t \`$1\`;                       echo ------------------------------;                       echo "如需要恢复请到~/.recycle目录里找回。"}print_help(){ cat <<-EOF        ${0##*/} version $VERSION        Usage: ${0##*/} [-r] [-f]  [file]...        del file and move it the recycle        EOF    # Handle unclosed quote for syntax highlighting '}### read optionoption=""while (( $# >= 1 )); do        case "$1" in                -h|--help)     print_help; exit 0;;                --)            shift; break;; #遇到`--',则option结束                -*)            option="${option}$1"; shift;;                *)                     break;;        esacdoneDATE=$(date +%Y%m%d_%H%M%S)while (( $# >= 1 )); do        #echo.log "$1"        mvToRecycle "$1"        shiftdone

recycle脚本:

#! /bin/bash# Copyright 2009 (c), devinwang# All rights reserved.## Filename   : recycle# Author     : devinwang# Date       : 20090506# Version    : 1.0 (init)# Usage      : # Description: configuration file template### =============================================# Version    : 1.1# Date       : 20090506# Author     : devinwang# Changes    : what is new[ -d ~/.recycle ] || mkdir ~/.recycleRECYCLE_DIR=~/.recycleVERSION=1.0### ^^^必须进入回收站所在的目录[[ -d ${RECYCLE_DIR} ]] || { echo err: \`${RECYCLE_DIR}\' is not dir; exit 22;}cd $RECYCLE_DIRif (( $? != 0 )); then        echo  -e "\\033[1;31mcannot change to dir$RECYCLE_DIR\\033[0m"        exit 1fi[[ "$PWD" == */.recycle ]] || { echo  -e "\\033[1;31mcwderr\\033[0m"; exit 9; }[[ "`echo ${RECYCLE_DIR}`" == "$PWD" ]] || { echo  -e"\\033[1;31mcwd err\\033[0m"; exit 9; }### ^^^必须进入回收站所在的目录function echo.log {        local line_no=${BASH_LINENO[0]}        local file_name=$0        echo "${file_name}:${line_no}:$@"}echo.ok() {        if [[ $1 == "-n" ]]; then                shift                echo -n -e"\\033[1;32m$@\e[0m"        else                echo -e"\\033[1;32m$@\e[0m"        fi}echo.err() {        if [[ $1 == "-n" ]]; then                shift                echo -n -e "\\033[1;31m$@\e[0m"        else                echo -e"\\033[1;31m$@\e[0m"        fi}function yesOrNo {    local answer=""    local ret=0    local message="$@, (Y)es/(N)o? [n] "    : ${REDIRECT:=/dev/tty}    while true ; do                read -p "${message}"answer < $REDIRECT > $REDIRECT 2>&1                case"$answer" in                       [yY]) ret=0; break ;;                       [nN]|"")         ret=1; break ;;                       *)       echo; continue                esac    done    return $ret}### ^^^list the files in recyclelistFile() {        lsOption=""        isHasSize=false        if [[ $option == *l* ]]; then               ls_option="${lsOption} -sh"                isHasSize=true        fi        ### file list        fileList="`ls -1 ${ls_option}${RECYCLE_DIR}`"        sortOption=""        ### sort by name        if [[ $option == *n* ]]; then               sortOption="${sortOption} -k4"        fi        if [[ $option == *r* ]]; then                sortOption="${sortOption}-r"        fi        ### sort the result        fileList=`echo "$fileList" |sort -t'_'${sortOption}`        offset_index=0        offset_year=$((0 + offset_index))        offset_month=$((4 + offset_index))        offset_day=$((6 + offset_index))        offset_hour=$((9 + offset_index))        offset_min=$((11 + offset_index))        offset_shortType=$((16 + offset_index))        offset_fileName=$((18 + offset_index))        while read i; do                #echo.ok "$i"                if [[ $i == total* ]];then                       echo $i                       continue                fi                if [[ $isHasSize ==true ]]; then                       size="${i%% *}"                       i="${i#* }"                fi               timeStr="${i:${offset_year}:4}-${i:${offset_month}:2}-${i:${offset_day}:2}${i:${offset_hour}:2}:${i:${offset_min}:2}"               shortType=${i:${offset_shortType}:1}               fileName=${i:${offset_fileName}}                if [[ $option == *l*]]; then                       #echo "$timeStr $size $shortType $fileName"                       printf "%s %-4s %s " "$timeStr" "$size""$shortType"                fi                ### must set""               colorOption=""                if [[ $shortType == d]]; then                       colorOption="\e[1;34m"                fi                echo -e"${colorOption}$fileName\e[0m"        done  <<< "${fileList}" ###here string### the while loop not exec in a subshell; if use pipeline, it will run in asubsehll;}### $$$list the files in recycleemptyRecycle() {                ### echo -e"\\033[1;32mpwd: ${PWD}\n\e[0m"                [[ "$PWD" ==*/.recycle ]] || { echo  -e "\\033[1;31mcwd err\\033[0m"; exit9; }                [[ "`echo${RECYCLE_DIR}`" == "$PWD" ]] || { echo  -e"\\033[1;31mcwd err\\033[0m"; exit 9; }                ###yesOrNo "emptythe recycle " && $RM -rfv $RECYCLE_DIR/* && echo.okrecycle emptyed || return 0                 $RM -rfv$RECYCLE_DIR/* > /dev/null && echo.ok recycle emptyed }### ^^^del files in recycledelFile() {        echo -e "\\033[1;32mpwd: ${PWD}\n\e[0m"        RM='/bin/rm'        #echo.log hi        #echo.log "$@"        time=0        size=0        while (( $# >= 1 )); do                case "$1" in                       -s)             local -i size=$2; shift2;;                       -t)             local -i time=$2; shift2;;                       -f)             local forec=true; shift;;                       -empty)                                        emptyRecycle                                       return $?                                       ;;                       *)                     break;;                esac        done        #echo.log $size        #echo.log $time        ### 同时sie和time同时为0则退出。        if (( size == 0 && time == 0 )); then                echo.err size and timeis \`0\'                return 1        fi        ### get the system date        date_now=`date -s now +%Y%m%d`        ### *MUST* 检测cwd是否为回收站,如果不是则exit        ### 防止误删其他目录        [[ "$PWD" == */.recycle ]] || { echo -e "\\033[1;31mcwd err\\033[0m"; exit 9; }        [[ "`echo ${RECYCLE_DIR}`" =="$PWD" ]] || { echo  -e "\\033[1;31mcwd err\\033[0m";exit 9; }        ### get the file in recycle        delFileListTmp="$(du -sb *)"        (( $? != 0 )) && return 1 ## recycle iempty        ### read line, and analize it        while read line; do                line_size=${line%%     *} ### get size                 line_f2=${line#*       } ### get file name: field 2               line_date=${line_f2:0:8} ### get del date                #echo.log $(( date_now- line_date ))                ### 删除符合条件的文件                if (( line_size >=size*1024*1024 && date_now - line_date >= time)); then                       ### 没有-f时,提示是否删除                       if [[ $forec != true ]]; then                               [[ "`echo ${RECYCLE_DIR}`" =="$PWD" ]] || { echo  -e "\\033[1;31mcwd err\\033[0m";exit 9; }                               yesOrNo remove \`$line_f2\' \                                       || continue                       fi                       ### 检测cwd是否为回收站,如果不是则exit                       ### [[ "$PWD" == */.recycle ]] || { echo  -e"\\033[1;31mcwd err\\033[0m"; exit 9; }                       ### [[ "`echo ${RECYCLE_DIR}`" == "$PWD" ]] || {echo  -e "\\033[1;31mcwd err\\033[0m"; exit 9; }                       $RM -fr $line_f2 && echo.ok remove \`$line_f2\'                       #echo.log "$line_size" $line_date                fi        done <<-EOF                ${delFileListTmp}        EOF        ### here document}### $$$del files in recycleprint_help(){ cat <<-EOF        ${0##*/} version $VERSION        Usage: ${0##*/} [-l] [-n] [-r]               ${0##*/} -d -empty               ${0##*/} -d [-f] [-t

recycle.sh脚本:

#!/bin/bashsize=`du -s /root/.recycle/ | awk '{print $1}'`date=`date +%F`if [ $size -gt 10485760 ]; then        recycle -d -empty &> /dev/null        echo "删除日期:$date" >> /var/log/recycle.logfi