写一个自定义rm命令

回复 收藏

linux系统的rm命令太危险,一不小心就会删除掉系统文件。 写一个shell脚本来替换系统的rm命令,要求当删除一个文件或者目录时,都要做一个备份,然后再删除。下面分两种情况,做练习:

1. 简单

假设有一个大的分区/data/,每次删除文件或者目录之前,都要先在/data/下面创建一个隐藏目录,以日期/时间命名,比如/data/.201703271012/,然后把所有删除的文件同步到该目录下面,可以使用rsync -R 把文件路径一同同步

2. 复杂

不知道哪个分区有剩余空间,在删除之前先计算要删除的文件或者目录大小,然后对比系统的磁盘空间,如果够则按照上面的规则创建隐藏目录,并备份,如果没有足够空间,要提醒用户没有足够的空间备份并提示是否放弃备份,如果用户选择y,则直接删除文件或者目录,如果选择n,则提示未删除,然后退出脚本。

2017-03-27 16:18 举报
已邀请:
0

小梁

赞同来自:

看不懂  刚开始学shell  晕晕的

0

Kry1702

赞同来自:

1

0

chenlei82486708

赞同来自:

1

0

JerryChan - 广东某工业大学大四拼命找offer的渣渣

赞同来自:

i_f32.gif写了个这个,老师您看看有哪里可以改进的地方

icon_txt.gif自定义rm.docx

0

LINUX_A - 不要在最能吃苦的年龄选择安逸!

赞同来自:

铭哥,我shell基础的也算是学完了吧,按照“跟阿铭学linux第二版” 开始学linux系统日常管理。这个我竟然写不出来  这正常吗?

0

chiang1213

赞同来自:

2.复杂

这里加了一些条件,如果删除的源文件大小为0则直接删除不备份,大小不为0的文件都带绝对路径备份到/data/.$(date +%Y%m%d%H%M)目录下。

#!/bin/bash

[ ! $# -gt 0 ] && exit 1

source /etc/profile

CANSHU="$*"

function make_filename () {

>/tmp/mv_filename.log

for SFI in $(echo ${CANSHU})

 do

  if [ -f $SFI -o -d $SFI ] 

   then

   SFILEPWD=$(pwd $SFI)

   DIRNAME=$(dirname ${SFI})

   SFILENAME=$(echo $SFI | sed -r 's#('"$DIRNAME"')\/(.*)\/?#\2#')

   echo "${SFILEPWD}/${SFILENAME}" >> /tmp/mv_filename.log

  fi

done

[ -s /tmp/mv_filename.log ] || echo -e "the file or directory is not exist:\n$CANSHU"

}

make_filename


function available () {

DANV=$(df -k|awk '$0 ~/ \/data$/{print $4}')

if [[ ! $DANV =~ [0-9]+ ]]

 then

 DANV=$(df -k|awk '$0 ~/ \/$/{print $4}')

fi

SANV=`cat /tmp/mv_filename.log|xargs -i -r du -k {}|awk 'BEGIN{num=0} {num=$1+num} END{print num}'`

if  [ ${SANV} -eq 0 ] ; then

RES=0 

elif [ $((${DANV}/${SANV})) -ge 1 ] ; then

RES=1

else

RES=2

fi

}

available


function movesfile () {

DIRGEN="/data"

DIRDATE=$(date +%Y%m%d%H%M)

[ ! -d ${DIRGEN}/.${DIRDATE} ] && mkdir ${DIRGEN}/.${DIRDATE}

 for SFILE in $(cat /tmp/mv_filename.log)

  do

   [ $(du -k $SFILE | awk '{print $1}') -eq 0 ] && ( /bin/rm -rf $SFILE || echo "rm $SFILE failed" ) && continue

  rsync -azR $SFILE ${DIRGEN}/.${DIRDATE}/ && /bin/rm -rf $SFILE || ( echo "rsync backup $SFILE failed and $SFILE is not deteled" )

 done

}


case $RES in

  0)

   /bin/rm -rf $(cat /tmp/mv_filename.log|tr "\n" " ")

   exit 0

  ;;

  1)

  movesfile

  ;;

  *)

  echo -n "the /data is low hd space,do you give up backup?(y/n): "

  read ennum

   case $ennum in

    y)

    cat /tmp/mv_filename.log | xargs -i -r /bin/rm -rf {}

    exit 0

    ;;

    *)

    echo "no file or directory is deleted"

    exit 0 

    ;;

    esac

   ;;

   esac


0

凶狠

赞同来自:

有标准答案吗?

0

LINUX_A - 不要在最能吃苦的年龄选择安逸!

赞同来自:

脚本可以实现所需求的效果,并且在其基础上改动了些,我认为没有必要精确到每分钟,因为假如在一个小时内每分钟删除一个文件 那待会你就会看到有50个目录,我直接是判断每小时是否有这个目录 每小时都删除的话 大概一天也就12个。 脚本执行的时候可以 添加多个参数,例如 rm sad sd  /asd/  不多讲了 看脚本,多多指正!

#! /bin/bash

##before delete file or dir, first we should total both of file or dir's size then move to another place
##written by zhdya_20171014

deldt=`date +%Y%m%d%H`
bakdir="/data"
trushsize=`df | egrep "/dev/sda3" | awk '{print $4}'`

if [ ! -d $bakdir/.$deldt ]
then
        mkdir -p $bakdir/.$deldt
else 
        for i in $*
        do
                filesize=`du -sh $i | awk '{print $1}'| sed 's/[a-zA-Z]//g'`
                if [ $filesize -gt $trushsize ]
                then
                        echo "The File or Dir's size already bigger than TRUSH. two option you can choice!!"
                        echo "if you type "y" it will delete the file or dir's directly!!!"
                        echo "if you type "n" it will end!!"
                        read -p "what's your opinion? [y/n]:" n
                        case $n in
                        y)
                                rm -rf $i
                                echo "already delete file and dir's directly"
                                exit
                        ;;
                        n)
                                echo "the file or dir's not delete."
                                exit
                        ;;
                        *)
                                echo "you input was wrong!!"
                                exit
                        ;;
                        esac
                else
                        mv $i $bakdir/.$deldt
                        echo "already deleted!!"
                fi
        done
fi

-----------------------------------------

修改~/.bashrc, 增加一行

[root@zhdy-03 ~]# cat ~/.bashrc

# .bashrc

# User specific aliases and functions

#alias rm='rm -i'

alias cp='cp -i'

alias mv='mv -i'

alias rm='sh /usr/local/sbin/rm.sh'

----------------------------------------

用我们自建的rm.sh替代rm命令

source ~/.bashrc 使替换立即生效

------------------------------------------------

当然 垃圾箱不能一直回收 也得写个脚本或者手动再或者添加个删除计划吧!

find /data/ -ctime 7 -type file -name "" -exec /bin/rm {} \;

回复帖子,请先登录注册

退出全屏模式 全屏模式 回复
评分
可选评分理由: