linux系统的rm命令太危险,一不小心就会删除掉系统文件。 写一个shell脚本来替换系统的rm命令,要求当删除一个文件或者目录时,都要做一个备份,然后再删除。下面分两种情况,做练习:
1. 简单
假设有一个大的分区/data/,每次删除文件或者目录之前,都要先在/data/下面创建一个隐藏目录,以日期/时间命名,比如/data/.201703271012/,然后把所有删除的文件同步到该目录下面,可以使用rsync -R 把文件路径一同同步
2. 复杂
不知道哪个分区有剩余空间,在删除之前先计算要删除的文件或者目录大小,然后对比系统的磁盘空间,如果够则按照上面的规则创建隐藏目录,并备份,如果没有足够空间,要提醒用户没有足够的空间备份并提示是否放弃备份,如果用户选择y,则直接删除文件或者目录,如果选择n,则提示未删除,然后退出脚本。
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
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 {} \;
2.复杂
#!/bin/bash
###定义变量
disk_maxspace=`df | sed -n '2,$'p | awk '{print $4}' | sort -nr | head -1`
bak_location=`df | sed -n '2,$'p | sort -k4 -nr | awk 'NR==1{print $6}'`
###定义函数
checkdir (){
cd $bak_location
if [ -d ".$(date +%Y%m%d)" ];then
echo "mu lu cun zai"
else
mkdir .$(date +%Y%m%d)
fi
}
###清空上次删除文件的大小记录
> /tmp/filesize.txt
###
for i in $*
do
du -s $i | sed 's/[a-zA-Z]//g' | awk '{print $1}' >> /tmp/filesize.txt
truthsize=`awk '{print $1}' /tmp/filesize.txt | awk '{(sum=sum+$1)};END{print sum}'`
if [ "$truthsize" -lt "$disk_maxspace" ];then
checkdir
mv $i ./.$(date +%Y%m%d)
else
echo "File or Dir's is too big"
read -p "y for delete/n for exit [y/n]:" n
case $n in
y)
rm -rf $i
echo "wen jian yi shan chu"
exit
;;
n)
echo "wei shan chu wen jian"
exit
;;
*)
echo "qing shu ru y/n"
exit
;;
esac
fi
done
有些地方还可以调整,目前删除的时候只能使用绝对路径
编辑回复