在linux中,为了防止误删设置回收站Trash来临时存放删除的文件!为了实现这个小功能,笔者将总结概括自己的知识,涉及到进程目录、脚本、临时文件tmpfiles、trash-cli工具等等。
一、恢复误删文件后进程存在的文件
在一个终端里面新建文件deletefile.txt,使用cat对中国文件做追加操作(ctrl+d确认输入的内容,这里不需要输入,只保持输入状态即可),即保持有个进程在操作这个文件。
在开一个终端,rm -f deletefile.txt删除这个文件。这里需要使用lsof工具,列出打开文件(lists openfiles)。
lsof | grep deletefile查找这个文件或者 lsof | grep deleted查找所有的deleted文件。
进入 进程目录,一般是进入/proc/pid/fd/ ,将文件名为1的文件,软连接到/home/lighthouse/deletefile.txt (deleted) ,复制到需要的目录中。
误删除的文件进程已经不存在,借助于工具才能恢复,可以使用第三方工具extundelete,笔者在此就不演示了,毕竟重点在于设置回收站Trash来防止误删。
二、简单的脚本实现每个用户的回收站Trash
原理很简单,重新将rm的别名,最简单的就是在环境变量里面设置rm的别名为: mv $@ ~/.trash/ 。
但是今天我们搞复杂点,设置为自定义函数trash。然后将下面的脚本置于/etc/profile.d下,通过. /etc/. profile来使其生效。关于系统环境变量以及用户环境变量的问题,以往的文章讲过好几次了,如有不栋请搜索以往的文章。置于系统环境变量下,是因为每个用户都需要生效,保存各自的回收站Trash。
$@ 都表示传递给函数或脚本的所有参数,在此指所有文件。
mkdir -p ~/.trash
alias rm=trash
alias rl='ls ~/.trash'
alias ur=undelfile
undelfile()
{
mypath=`pwd`
cd ~/.trash
mv -i $@ $mypath
cd $mypath
}
trash()
{
mv $@ ~/.trash/
}
cleartrash()
{
read -p "clear sure?[n]" confirm
[ $confirm == 'y' ] || [ $confirm == 'Y' ] && /bin/rm -rf ~/.trash/*
}
我们来测试一下。脚本中三个函数的功能以及别名都正常。删除于恢复多文件也正常,笔者就不测试了。
笔者觉得最后又将这个脚本优化了一下,将rm改为了srm,alias srm=trash,意为safe rm 。目的是为了系统脚本中的rm区分开,因为其他的脚本后台执行的rm删除不需要人为保存,还有脚本中rm带参数的话,可能会使rm命令失效。那么在以后命令行的运维过程中就可以推荐使用srm,而非直接暴力的使用rm!
Bash 别名仅在交互式 shell 中使用,因此使用此别名不应干扰期望使用 rm 的脚本,也可以rm前面加上一个反斜杠来绕过别名,\rm 。同时可以将 rm 别名为会提醒您不要使用它的东西,alias rm='echo "This is not the command you are looking for."; false' 。命令行就可以直接屏蔽rm命令,脚本中或者真正需要时使用/rm ,\rm file-without-hope 。
三、定时清理回收站Trash
利用crontab脚本来定时清理每个用户的回收站Trash中的过期文件,防止回收站文件过多。可以使用脚本中的
以前笔者做过crontab脚本来删除过期的用户操作日志和mysql数据库操作日志,脚本类似,置于/etc/cron.daily下:
delete_time=15
find trash目录 -mtime +$delete_time -exec rm -r {} \;
需要注意的是,每个用户都有一个回收站Trash,那么需要每个用户都设置crontab定时任务来完成清理工作吗?是不是过于麻烦了,特别是用户多的情况下。
四、Linux临时文件tmpfiles来完成清理
笔者写过一篇文章-Linux管理临时文件tmpfiles,里面根据systemd-tmpfiles-clean.timer进行管理systemd-tmpfiles-clean.service服务,开机15分钟执行服务或者隔一天执行一次清理。服务又是调用程序/usr/bin/systemd-tmpfiles --clean 来清理被标记的文件目录。
那么那些文件会被标记清理呢?通过man systemd-tmpfiles查看:systemd-tmpfiles creates, deletes, and cleans up volatile and temporary files and directories, based on the configuration file format and location specified in tmpfiles.d(5).
找到 tmpfiles.d目录下的tmp.conf,清理/tmp目录超过10天的内容以及清理/var/tmp目录超过30天的内容,同时带x标记的是忽略指定的路径及该路径下的所有内容。
那么我们就可以将每个用户的回收站Trash置于/tmp目录下,让systemd帮我们管理。
现在笔者来改写一下这个脚本。关于文件权限问题,测试了好久,坑!
trash_path=/tmp/trash/`whoami`
if [ ! -d /tmp/trash ]
then
mkdir -p /tmp/trash
chmod 777 /tmp/trash
fi
if [ ! -d ${trash_path} ]
then
mkdir ${trash_path}
chmod 700 ${trash_path}
fi
alias srm=trash
alias rl="ls $trash_path"
alias ur=undelfile
undelfile()
{
mypath=`pwd`
cd $trash_path
mv -i $@ $mypath
cd $mypath
}
trash()
{
mv $@ $trash_path
}
cleartrash()
{
read -p "clear sure?[n]" confirm
[ $confirm == 'y' ] || [ $confirm == 'Y' ] && /bin/rm -rf $trash_path/*
}
最后在/tmp/trash目录下生成了用户文件夹!
既然回收站都放在一个文件夹了,那么其实就可以使用用户操作日志或者数据库操作日志的清理方法了,详情参考笔者以前的文章。自己定义清理周期比systemd更加灵活。还有一点,要是长期没有使用srm,把权限为777的trash目录给删除了,下一次普通用户登录时是没有权限建立777的trash目录的!当然可以脚本上添加权限也可以搞定。
所以,最好还是和以前文章一样,在其他地方 比如/opt目录建立trash目录,下面再建立各个用户的目录,根据cron来定期清理。
五、trash-cli工具
trash-cli是一个使用 python 开发的软件包。笔者在树莓派4B中进行测试,使用apt install trash-cli 安装,既然是python开发也可以使用python的包管理工具pip install trash-cli来安装。Trash-Cli 可以工作的很好,有一些替代品,也可以试一试 gvfs-trash 和 autotrash 。
回收站对应的目录是 $HOME/.local/share/Trash 。
trash-cli命令如下,可以使用man来产看使用方法。
trash-put: 删除文件和目录(仅放入回收站中),也可以trash
trash-list :列出被删除了的文件和目录
trash-restore:从回收站中恢复文件或目录 trash.
trash-rm:删除回收站中的文件
trash-empty:清空回收站
测试如下,files文件夹存放删除的文件,info文件夹存放源目录以及删除时间,expunged未知。
如何自动删除回收站过期文件呢?建立用户cron定时任务。这将使用垃圾清空命令更新您的 crontab 文件,该命令每天运行并删除超过 30 天的文件。
(crontab -l ; echo "@daily $(which trash-empty) 30") | crontab -
六、设置回收站Trash的高级脚本
github上有个saferm.sh脚本可以使用,这里就不再赘述了,请读者自行搜索查看吧。
网友评论