UNIX、Linux 下的 rm 删除文件后难以恢复,很多人会设置别名 rm=‘rm -i’,但删除时的提示很烦人,而且会被 rm -rf 的 -f 覆盖,不会提示。于是,很多人会写替代版的 rm,思路很简单,把 rm 变成 mv 语义,按日期放入某个 Trash 目录,很多年前我也写过一段穷人的回收站:
## in ~/.bashrc
safe_rm () {
local d t f s
if [ -z "$PS1" ]; then
/bin/rm "$@"
else
d="${TRASH_DIR:=$HOME/.__trash}/`date +%Y%m-%W`"
t="`date +%F_%H-%M-%S`"
mkdir -p "$d" || return
for f do
[ -e "$f" ] || {
echo "Not found: $f" >&2
continue
}
perl -MCwd -e 'index(Cwd::abs_path($ARGV[0]), $ARGV[1]) == 0 ? exit(1) : exit(0)' \
"$f" "${TRASH_DIR:-$HOME/.__trash}" || {
echo "Please use /bin/rm or \rm to delete files in trash." >&2
continue
}
s=$d/`basename "$f"`-$t-$RANDOM
# Loudly, train users to be careful without this message.
echo "Move $f to $s ..."
/bin/mv "$f" "$s" || break
done
echo -e "[$? $t `whoami` `pwd`] $@\n" >> "$d/00rmlog.txt"
fi
}
alias rm=safe_rm
今天刚注意到 FreeDesktop 定义过回收站规范,有两个跨平台的命令实现:
使用 Python 编写,被 Debian 收录了,它提供如下命令:
trash: 移动文件到回收站(默认在~/.local/share/Trash),并记录原路径和删除时间;trash-empty:清空回收站,支持清空多少天以前的文件;trash-list:列出被删文件的原路径和删除时间;trash-put: 同 trash 命令;trash-restore:恢复文件,存在多个被删的同名文件时会询问恢复哪个;trash-rm: 删除回收站中的文件,注意这个命令不询问,有同名文件时会全部删除;
这个工具缺一个 UI 去查看被删文件的内容,不过也问题不大,进 ~/.local/share/Trash 查看即可。
这个工具比 trash-cli 功能更多,UI 更友好,使用 Go 编写,提供了 gtrash 命令,这个命令有如下子命令:
gtrash find: 列举回收站中的文件,可以按名字和时间过滤,并能顺带清除或恢复;gtrash prune:按日期和大小清除回收站中的文件;gtrash put:rm的替代gtrash restore:恢复文件,这个命令会展示一个 TUI 界面,能预览文件内容,非常好用;gtrash restore-group:按秒级范围的删除时间成组的恢复文件;gtrash rm:删除回收站中的文件,会询问,但不能选择删除同名文件中的某一个;- `gtrash summary: 显示回收站里有几个文件,占据多少磁盘空间;
虽然两个工具的文档都不建议用alias rm='trash-put' 而是建议设个其它的别名比如 del,但我还是选择直接用 alias rm='...',已经太习惯这个命令了。