红联Linux门户
Linux帮助

Linux回收站的设计与实现

发布时间:2017-01-13 11:12:30来源:linux网站作者:安翔
作为Linux系统管理员或者软件开发人员,当你使用rm命令删除文件之后发现该文件依然有用但无法恢复,或者使用 ‘rm -rf’强制误删了某些文件时,是否为此感到痛苦不堪。是否苦恼于Linux缺乏类似Windows系统的回收站。虽然某些Linux图形界面具有回收站功能,但是在命令行中依然缺乏回收站功能的支持。本文通过shell脚本实现一个回收站命令trash,提供基于Linux系统命令行的回收站功能,让误删的文件能够恢复如初。在多数情况下,你可以使用trash命令替代rm命令进行删除文件操作。此命令可运行在带bash的Linux server、Linux桌面系统、嵌入式Linux系统上。
 
回收站功能简介
通过usage函数显示trash命令的帮助信息。
function usage(){
echo "Function: Put files or directories in trashcan."
echo "Usage: trash [OPTION]... FILE..."
echo "Options:"
echo "    -h | -help        Show the help mesage"
echo "    -t | -trash       Move contents to trashcan"
echo "    -f | -force       Delete contents forcely"
echo "    -l | -list        List contents in trashcan"
echo "    -r | -restore     Restore the contents in trashcan"
echo "    -d | -delete      Delete contents from trashcan"
echo "    -e | -empty       Empty trashcan"    
echo "    -c | -config      Configure crontab task,empty trashcan regularly"
}
执行trash -h或者trash不带参数时,显示trash命令帮助信息如下:
Linux回收站的设计与实现
trash命令删除文件时,实际上是将文件移动到用户根目录的trashcan目录中,同时将文件名、删除时间、原始路径记录在.record隐藏文件中;通过trash -r选项可将文件从回收站中恢复到原始路径;确信文件可删除的情况下,可使用trash -f进行彻底删除操作;trash -d和-e选项用于清除回收站中文件;执行trash -c将清理回收站指令添加到crontab任务中,系统会定期自动清理回收站。
 
初始化
运行trash命令时,首先进行初始化,代码片段如下:
PATH_TRASHCAN=~/trashcan
PATH_RECORD=$PATH_TRASHCAN/.record
PATH_CRON=/var/spool/cron
function init(){
if [ ! -d $PATH_TRASHCAN ]
then
mkdir $PATH_TRASHCAN
chmod 600 $PATH_TRASHCAN
fi
}
定义回收站目录,用于存放删除的文件或者文件夹。Trash命令在当前用户根目录中新建trashcan目录来存放文件。如代码所示,init函数首先判断trashcan目录是否存在,如果不存在,则新建该目录且将trashcan目录权限设置为当前用户可读写,禁止其他用户对trashcan目录的访问权限。
 
参数判断以及处理
初始化完成之后,需要对trash命令的参数进行判断和处理。
if [ $# -ge 1 ]
then
declare param=()
param_circle=0
for i in $@; do
param[param_circle]=$i
param_circle=$(($param_circle+1))
done
unset param[0]  
case "$1" in
-h)
usage
;;
-t) 
trash
;;
-f)
force
;;
-l)
list
;;
-r)
restore
;;
-d)
delete
;;
-e)
empty
;;
-c)
config 
;;
-o)
cron_delete 
;;
*)
echo "$1 is not an option"
usage
;;
esac
else
usage  
fi
首先判断trash命令输入的参数个数,如果小于1,则调用usage函数提示用户trash命令的正确使用方法。如果大于等于1,证明trash命令使用方式合法,此时将所有参数存放到param数组中,使用unset param[0]删除第一个参数,保留所有文件名内容在param数组。接下来根据第一个参数的值,分别调用相应的函数。
 
删除文件到回收站
功能说明
当输入trash -t 时调用trash函数将文件移动到回收站。判断param数组长度,如果小于1说明trash -t后没有指定被删除文件名称;如果大于等于1则循环处理输入的所有文件。
当文件、文件夹大于200M时对其进行强制删除,考虑到大多数嵌入式平台Flash存储空间非常有限。
给被删除文件添加时间戳,目的是通过时间戳区别同名文件且能够清晰显示删除时间。
获取被删除文件的原始路径,以便从回收站恢复。
调用record函数记录删除文件信息。
通过mv命令将文件移动到trashcan目录中。
function trash(){
if [ ${#param[@]} -lt 1 ]
then
echo "Please input the files you want to trash!"
echo ">trash -t [file1]..."
else
file_circle=1
TotalFileSize=0
for file in ${param[@]}
do
if [ -f "$file" ] 
then
fileSize=`ls -l $file|awk ' {print $5}'` 
if [ $fileSize -gt $(( 200*1024*1024 )) ]
then
echo "$file size is larger than 200M, will be deleted directly"
`rm -rf $file`
unset param[$file_circle]
else
TotalFileSize=$[TotalFileSize+fileSize]
fi
elif [ -d "$file" ] 
then
dirSize=`du -sb $file|awk '{print $1}'`
if [ $dirSize -gt $(( 200*1024*1024 )) ]
then
echo "dir: $file size is larger than 200M, will be deleted directly"
`rm -rf $file`
unset param[$file_circle]
else
TotalFileSize=$[TotalFileSize+dirSize]
fi
fi
file_circle=`expr $file_circle + 1`
done
for file in ${param[@]}
do
currentTime=`date +%Y-%m-%d_%H:%M:%S`
trashFile="${file##*/}_${currentTime}"
trashPath="$(pwd)/$file"
if mv -f $file $PATH_TRASHCAN/$trashFile
then 
record $trashFile $trashPath
echo "$file is trashed"
fi
done
fi
}
 
record函数
将带有时间戳的文件名以及文件的原始路径记录在~/trashcan/.record文件中。
PATH_RECORD=$PATH_TRASHCAN/.record
function record(){
if [ ! -f $PATH_RECORD ]
then 
touch $PATH_RECORD
chmod 644 $PATH_RECORD
fi
echo $1 $2>> $PATH_RECORD
}
 
强制删除
如果想要彻底删除文件可以使用trash -f,调用force函数通过rm -rf命令强制删除文件或者目录。
function force(){
rm -rf ${param[@]}
}
使用示例如下:
Linux回收站的设计与实现
通过ll -a ~/trashcan显示trashcan目录为空。trash_test为删除文件的原始目录,其中具有file1和file2两个文件。执行trash -t file1 file2将file1和file2删除到回收站trashcan中,执行后可以发现回收站中产生了file1和file2带时间戳的文件,同时trash_test目录中相应的文件消失。
 
显示回收站内容
function list(){
cat $PATH_RECORD
}
通过trash -l命令可随时随地查看回收站内容,不用访问回收站目录去查看。可以看到所有删除的文件名、删除时间、原始路径。
 
恢复文件
输入trash -r [FILE]将FILE文件恢复到原始路径。
首先判断trash -r后面是否输入了文件名,若没有则提示用户输入。
从.record文件中找到恢复文件的原始路径。
通过mv将文件移动到原始路径。
同时将恢复的文件记录从.record文件中删除。
function restore(){
if [ ${#param[@]} -lt 1 ]
then
echo "Please input the files you want to restore!"
echo ">trash -r [file1]..."
else
for file in ${param[@]}
do
restorePath=$(awk /$file/'{print $2}' $PATH_RECORD) 
fileRestore=$(awk /$file/'{print $1}' $PATH_RECORD)
$(mv  $PATH_TRASHCAN/$fileRestore $restorePath)
echo "$fileRestore is restored to $restorePath"
$(sed -i /$fileRestore/'d' $PATH_RECORD)
done
fi
}
使用示例如下:
Linux回收站的设计与实现
通过以上示例可以发现回收站中具有file1和file2两个带有时间戳的文件,且.record中记录了原始路径,此时trash_test目录为空。执行trash -r file*命令恢复所有file开头的文件,成功恢复了file1和file2文件,且删除了.record中的记录信息。
 
清理回收站
手动删除
通过trash -d删除指定文件。
Delete函数首先判断trash -d是否指定了文件。如果为空则提示用户输入想要删除的回收站中文件。
反之,循环处理文件。使用rm -rf彻底删除文件或者文件夹。
同时将文件记录从.record文件中删除。
function delete(){
if [ ${#param[@]} -lt 1 ]
then
echo "Please input the files you want to restore!"
echo ">trash -d [file1]..."
else
for file in ${param[@]}
do
fileDelete=$(awk /$file/'{print $1}' $PATH_RECORD)
$(rm -rf $fileDelete)
echo "$fileDelete is deleted"
$(sed -i /$fileDelete/'d' $PATH_RECORD)
done
fi
}
 
清空回收站
通过trash -e命令清除回收站中所有内容。
Empty函数调用rm -rf删除~/trashcan目录中的所有文件以及隐藏文件.record。
function empty(){
rm -rf $PATH_TRASHCAN/*
rm -rf $PATH_RECORD
}
 
crontab自动清理
配置crontab任务,每隔30分钟删除回收站中存放时间大于7天的文件。
执行trash -c将定期清除回收站文件的指令加入到crontab中。
通过crontab -l新建用户cron文件。
设置为每隔30分钟执行一次清理操作,该时间可灵活调整。
echo "*/30 * * * * trash -o $regularTime " >> $PATH_CRON/$USER
trash -c后参数为天数,如果为空则默认每隔30分钟删除回收站中存放超过7天的文件,否则删除超过指定天数的文件。
配置crontab任务函数config代码清单:
function config(){
if [ ${#param[@]} -lt 1 ]
then 
regularTime=7
else
regularTime=${param[1]}
fi
crontab -l > $PATH_CRON/$USER
# echo "* * * * * echo "delete files which were older than $regularTime days">`tty` " >> $PATH_CRON/$USER
$(sed -i /trash/'d' $PATH_CRON/$USER)
echo "*/30 * * * * trash -o $regularTime " >> $PATH_CRON/$USER
crontab $PATH_CRON/$USER
crontab -l
}
定期清除函数:
function cron_delete(){
if [ ${#param[@]} -lt 1 ]
then 
regularTime=7
else
regularTime=${param[1]}
fi
arrayCron=($(find $PATH_TRASHCAN/* -mtime +$regularTime))
for file in ${arrayCron[@]}
do
$(rm -rf $file)
fileRecord="${file##*/}"
$(sed -i /$fileRecord/'d' $PATH_RECORD)
done
}
使用示例如下:
Linux回收站的设计与实现
终端显示*/30 * * * * trash -o 8则表示该任务已成功添加到crontab中。
注意:
PATH_CRON=/var/spool/cron
该路径需根据用户系统实际路径更改。例如:ubuntu实际路径为/var/spool/cron/contabs。
 
总结
本文使用shell脚本实现了简易的命令行Linux回收站功能。用户只需将trash脚本拷贝到Linux环境变量目录中,给予执行权限,即可使用该功能,建议使用trash命令替代rm命令进行删除操作,减少误删造成的损失。
 
源码地址:https://github.com/IOT-er/trashcan
 
本文永久更新地址:http://www.linuxdiyf.com/linux/27776.html