linux下建立回收站防止误删除及定期清空
功能描述:
我们都知道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 --help Usage: rm [-r] [-f] [file]... del file and move it the recycle 与系统自带的rm命令参数一致 复制代码 $ recycle --help recycle version 1.0 Usage: recycle [-l] [-n] [-r] recycle -d -empty recycle -d [-f] [-t <time>] [-s <size>] manipulate the recycle Options: l - list the deleted file with long format n - sort the deleted file by name r - list the deleted whth reverse order d - delete file mode empty - empty the recycle h - Help t <time> - delete the file `time‘ days ago s <size> - delete file which size greater the `size‘ megabyte 复制代码
如果要定期清空回收站的话,就添加一个计划任务。
环境描述:
现在我有不止一台的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/rm salt ‘*‘ cp.get_file salt://files/recycle /usr/local/bin/recycle salt ‘*‘ cp.get_file salt://files/recycle.sh /usr/local/bin/recycle.sh salt ‘*‘ 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 ~/.recycle RECYCLE_DIR=~/.recycle VERSION=1.0 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 } 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 option option="" while (( $# >= 1 )); do case "$1" in -h|--help) print_help; exit 0;; --) shift; break;; #遇到`--‘,则option结束 -*) option="${option}$1"; shift;; *) break;; esac done DATE=$(date +%Y%m%d_%H%M%S) while (( $# >= 1 )); do #echo.log "$1" mvToRecycle "$1" shift done
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 ~/.recycle RECYCLE_DIR=~/.recycle VERSION=1.0 ### ^^^ 必须进入回收站所在的目录 [[ -d ${RECYCLE_DIR} ]] || { echo err: \`${RECYCLE_DIR}\‘ is not dir; exit 22;} cd $RECYCLE_DIR if (( $? != 0 )); then echo -e "\\033[1;31mcannot change to dir$RECYCLE_DIR\\033[0m" exit 1 fi [[ "$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 recycle listFile() { 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 recycle emptyRecycle() { ### 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 recycle delFile() { 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 recycle print_help() { cat <<-EOF ${0##*/} version $VERSION Usage: ${0##*/} [-l] [-n] [-r] ${0##*/} -d -empty ${0##*/} -d [-f] [-t<time>] [-s <size>] manipulate the recycle Options: l - list the deleted file with long format n - sort the deleted file by name r - list the deleted whth reverse order d - delete file mode empty - empty the recycle h - Help t <time> - delete the file\`time‘ days ago s <size> - delete file which sizegreater the \`size‘ megabyte EOF } ### read option option="" while (( $# >= 1 )); do case "$1" in -h|--help) print_help; exit 0;; -d) option="${option}$1"; shift; break;; --) shift; break;; #遇到`--‘,则option结束 -*) option="${option}$1"; shift;; *) break;; esac done if [[ $option == *-d* ]]; then #echo.log $option delFile "$@" else listFile fi
recycle.sh脚本:
#!/bin/bash size=`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.log fi
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。