最近一段时间学习了一些Linux的基本操作,对bash和shell脚本也有了一些了解,同时在使用linux命令行时,也碰到了一个常见的问题,就是使用rm误删文件之后很难恢复,于是就想着自己重写一个delete命令来代替rm工作。正好也是用shell来练练手自己写个小脚本。
主要工作流程
1.delete内部实际上还是调用了rm来做实际的删除工作,因此使用方法和rm完全一样
2.在使用delete命令时,会首先将要删除的文件拷贝到一个自己定义的家目录下的模拟回收站garbage目录中去,然后再执行删除操作。
3.在回收站中还是会根据每次delete操作自己创建一个目录并把文件放进去,目录名就是当前操作的时间节点,这样做是为了后面打算再写一个恢复的命令,以方便要查找的文件。
4.对于garbage目录保留的文件,写了一个例行性工作调度(crontab),每隔1天会进行一次清空。
5.调用recover命令可以将删除的文件恢复到当前文件夹下,该命令默认恢复上一次删除操作的所有文件,等同于显示添加参数-l,还有一个-f参数可以接具体文件名,恢复指定的文件。
缺陷
1.虽然也可以同时删除多个文件,但是对于以连接符“-”开头的或者中间含有空格的文件名的文件删除会出错,目前还没有想好解决方案。产生原因是因为在写脚本时为了提取出要拷贝的文件名,对命令行进行了逐参数分析。参数分析比较简单所以对于上述两种情况难以避免。
2.自己设置的例行性工作只是在每天早上六点半就全部清空所有回收站的文件,并没有考虑到文件是什么时候删除的。
3.对于recover命令的-f参数后接的文件名不支持通配符,因为将通配符作为参数传递的时候会根据当前文件夹中文件名字而被展开,自己想了很多办法没有改成功,就暂时放弃了。以后有想法再更新。
4.暂时只碰到这个问题,后面再多用用,碰到问题再回来改改。有幸看到这篇文章的朋友如果有兴趣也可以自行copy下来试验一下。出现问题可以一起讨论一下。
说明
1.直接在/bin目录下创建一个文件delete,把代码copy进去即可
2.chmod a+x delete //添加可执行权限,然后就可以像rm一样使用了
3.模拟了一个回收站是在自己用户目录下创建的,同时为了不影响日常操作,就使用了隐藏文件的方式,名字为~/.garbage
4.该回收站目录会根据你登录用户的不同放在不同用户目录下,是不共用的,若想要使用一个目录,可以直接修改下面代码中dest变量即可。
- delete 脚本
#!/bin/bash
#Program:
# when use delete,the file will be copy to you home's garbage and then delete
#History:
# Verision 1.0 2018/7/16 just copy current directory's file ,not surpport path //使用下来看应该是支持路径删除的= =懒得改说明了
# can't deal with filename that has blank or begin with "-"
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#judging input parameters'numbers
if [ "$#" -lt 1 ];then
echo "please input file name"
exit 0
fi
dest=~/.garbage
#extract filename from input ,by delete str such as "-*"
var=$@
prem=""
for str in ${var}
do
if [[ $str != -* ]]; then
prem="$prem $str"
#echo "$str != -*"
#else
#echo "$str == -*"
fi
done
#echo ${prem}
#find each filename is exit or not
for filename in ${prem}
do
if [ ! -e $filename ];then
echo " no $filename file in current directory"
exit 0
fi
done
#if there is no garbage,mkdir it
if [ ! -d ${dest} ] ;then
mkdir ${dest}
fi
#mkdir a directory named with time,represent current operation
Date=$( date +%y%m%d-%s )
if [ ! -d ${dest}/${Date} ] ;then
mkdir ${dest}/${Date}
fi
# copy the files to garbage,if success,then rm them,or rm the date directory
cp -rf $prem ${dest}/${Date}
if [ $? -eq 0 ] ; then
echo "delete and copy correct"
rm ${var}
else
rm -rf ${dest}/${Date}
echo "copy to garbage false"
exit 0
fi
- recover命令
#!/bin/bash
# Program:
# this command is for revover file that you have deleted
# History:
# Version 1.0 2018/7/18 this command have two parameter,you can recover specified file ,or last deleted file,the recoverd file
# will copy to current directory,and garbage's file will be deleted。
# what's more,parameter -r [filename] filename dosen't support wildcard character
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
export PATH
dest=~/.garbage
last=$( ls ${dest} -t | head -n 1 )
if [ "$#" -lt 1 ] || [ "$1" = "-l" ];then
if [ "$last" = "" ];then
echo "the garbage is empty"
exit 0
fi
if [ "`ls ${dest}/${last}`" = "" ];then
echo "last delete have no data"
exit 0
fi
cp -rf ${dest}/${last}/* ./
if [ $? -eq 0 ];then
echo "recover last file success"
rm -rf ${dest}/${last}
exit 0
else
echo "recover last file failed"
exit 0
fi
fi
IsExist=0
function testfileandcopy(){
dirs=$( ls ${dest} -t )
for dir in $dirs
do
#echo ${dest}/${dir}/$1
if [ -e "${dest}/${dir}/$1" ];then
cp -rf ${dest}/${dir}/$1 ./
rm -rf ${dest}/${dir}/$1
IsExist=1
fi
done
if [ "$IsExist" -eq 0 ];then
echo "$1 is not exist in garbage"
else
echo "$1 has been recover success"
fi
IsExist=0
}
var=$@
if [ "$1" = "-f" ] && [ "$#" -ge 2 ];then
if [ "$last" = "" ];then
echo "the garbage is empty"
exit 0
fi
prem=${var#-f* }
#echo "$prem"
for filename in "$prem"
do
testfileandcopy "$filename"
done
elif [ "$1" != "-f" ];then
echo "please input right parameter: -r or -f "
exit 0
else
echo "please input filename"
exit 0
fi
- 例行性工作调度
corntab -e
30 06 * * * clrgarbage
以下为clrgarbage命令,同上放在/bin文件夹中
#!/bin/bash
#Program:
# this shell is for clear garbage,include every users garbage
#History:
# Version 1.0 2018/7/17 use this command will clear garbage directly,not consider delete time
#
PATH=/bin:/sbin:/usr/bin:/usr/sbin/:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
dest=.garbage
if [ -d /root/${dest} ] && [ "`ls -A /root/${dest}`" != "" ];then
rm -rf /root/${dest}/*
if [ $? -eq 0 ];then
echo "clear root garbage success"
else
echo "clear root garbage failed"
exit 0
fi
elif [ ! -d /root/${dest} ];then
echo "root has no garbage"
else
echo "root/${dest} is empty"
fi
users=$( ls /home/ )
for username in $users
do
if [ -d /home/${username}/${dest} ] && [ "`ls -A /home/${username}/${dest}`" != "" ];then
rm -rf /home/${username}/${dest}/*
if [ $? -ne 0 ];then
echo "clear ${username} garbage success"
else
echo "clear ${username} garbage failed"
exit 0
fi
elif [ ! -d /home/${username}/${dest} ];then
echo "${username} has no garbage directory"
else
echo "${username}/${dest} is empty "
fi
done