使用linux时,经常会执行rm -rf命令,但是这一命令是有风险的,例如,执行某个shell脚本,shell脚本中有如下语句:
# script.sh
rm -rf $HOME/$SOME_PATH
此时,如果因为某项设置,导致环境变量SOME_PATH为空,则会直接把HOME目录下的所有内容清空。我在使用开发套件进行开发时,也出现过误删某一项目,导致本地和远程分支的代码一同被删除的问题,废了好大的劲才找到commit id恢复过来,和同事吐槽这一点的时候,同事表示自己做了个回收站功能,我一时兴起,也尝试做了个简单的回收站。
要实现一个类似windows回收站的功能,需要考虑以下问题:
- linux通常是多用户使用,这一脚本不应影响其他用户,即仅能在当前用户下使用,理想情况下,该脚本不能提升为root;
- 同一文件被多次删除时,应当能选择其中一项从回收站中进行恢复;
- 应当能查看被删除文件的meta信息,例如,size,被删日期,原路径,etc;
- 能正确处理文件/目录/软链接;
- 能识别正则匹配的参数,例如rm -rf test*,能匹配出test1,test2,etc
这个功能并不难实现。
针对第一点,将该用户脚本限定在HOME目录下即可;
针对第二点,可通过绝对路径+被删日期生成的hash值/md5来唯一标识某个文件,并提供恢复文件的脚本;
针对第三点,可提供一个文件,专门用于记录被删除的文件的必要信息;
第四点无需操心,linux下一切皆文件;第五点实测发现,shell脚本会对正则匹配的参数展开为实际值。
该功能主要分为两个部分,分别为remove.sh和recover.sh,其共同操作一个recycle目录以及一个meta文件,对于两者公用的变量,放在init.conf中。
将文件移到回收站
#!/bin/bash
# remove.sh
source ./init.conf
# init
if [ ! -d ${TRASH} ]
then
mkdir ${TRASH}
echo “recycle ${TRASH} created”
fi
if [ ! -f ${TRASH_META} ]
then
touch ${TRASH_META}
echo “file ${TRASH_META} created”
fi
# do remove
for f in $*
do
if [ ! -e ${f} ]
then
echo -e "\e[31m WARN \e[0m: ${f} not exists"
else
real_path=$(realpath ${
f})
if [ ${real_path} = ${TRASH} -o ${real_path} = ${TRASH_META} ]
then