Linux、mac的命令行下没有回收站功能,很多时候手一抖就把重要文件给 rm -fr * 了,虽然linux下有可能通过lost +found/debugfs找回,但难度也比较大,不能保证一定能够找回。人总是会犯错,本人工作这几年也犯过3次rm -fr删除后后悔的错误,与其后悔不如防范于未然,像桌面操作系统(windows、mac os、Ubuntu)一样加个回收站机制就可以了,经过几天的努力终于实现了,放到github上了,欢迎使用。
源码地址:https://github.com/LaiJingli/rmtrash
rmtrash 是linux和mac下命令行版本rm的回收站,安装后对用户透明,符合正常使用rm的习惯,有了他再也不怕rm时候手颤抖了。
rmtrash stands for "rm trash" which acts just like the system built-in rm command,and just moves the file to the trash for recovery when needed.
提醒:rmtrash主要用于防止人为误删除操作,回收站本身不能替代系统正常的数据备份操作,数据备份依然非常重要。
主要参考了如下2篇文章,向作者表示感谢:
源码地址:https://github.com/LaiJingli/rmtrash
回收站功能在 Linux 中的实现: http://www.ibm.com/developerworks/cn/linux/1410_licy_linuxtrash
Bash Getopts - 让你的脚本支持命令行参数: http://linux.cn/article-3204-1.html
源码如下:
#!/bin/bash
### rmtrash,rm command line recycle bin for linux and mac osx.
### rmtrash 是linux和mac下命令行版本rm的回收站,安装后对用户透明,符合正常使用rm的习惯(支持rm -fr file哦),有了他再也不怕rm时候手颤抖了。
### rmtrash stands for "rm trash" which acts just like the system built-in rm command,and just moves the file to the trash for recovery when needed.
### https://github.com/LaiJingli/rmtrash
### laijingli2006@gmail.com
### -- ###trash目录define
realrm="/bin/rm"
trash_dir=~/.rmtrash/
trash_log=~/.rmtrash.log
###判断trash目录是否存在,不存在则创建
if [ ! -d $trash_dir ] ;then
mkdir -v $trash_dir
fi ###动态修改用户shell中的alias配置
os_type=`uname`
shell_path=$SHELL
shell_type=`echo $SHELL|awk -F/ '{print $NF}'`
alias_file=~/.${shell_type}rc
alias_rm=`cat $alias_file|grep ^"alias rm="`
return_value=$?
#echo return_value: $return_value
#echo alias_rm: $alias_rm
###如果不存在rm alias,则生成
if [[ $return_value -ne ]] ;then
echo first time to run rmtrash
echo "alias rm=/bin/rmtrash.sh" >>$alias_file && source $alias_file
###如果存在rm alias,且不是指向rmtrash的,则注释掉,区分linux 和mac
elif [[ "$alias_rm" != "alias rm=/bin/rmtrash.sh" ]];then
echo already has alias rm,and must commit out
if [[ $os_type == Darwin ]];then
sed -i .bak 's/^alias\ rm=/#alias\ rm=/g' $alias_file && \
echo "alias rm=/bin/rmtrash.sh" >>$alias_file && \
source $alias_file
elif [[ $os_type == Linux ]];then
sed -i.bak 's/^alias\ rm=/#alias\ rm=/g' $alias_file && \
echo "alias rm=/bin/rmtrash.sh" >>$alias_file && \
source $alias_file
fi
fi ####function define
###usage function
rm_usage () {
cat <<EOF
Usage1: `basename $` file1 [file2] [dir3] [....] delete the files or dirs,and mv them to the rmtrash recycle bin
Usage2: rm file1 [file2] [dir3] [....] delete the files or dirs,and mv them to the rmtrash recycle bin
rm is alias to `basename $`.
options:
-f mv one or more files to the rmtrash recycle bin
-r mv one or more files to the rmtrash recycle bin
-fr mv one or more files to the rmtrash recycle bin
-rf mv one or more files to the rmtrash recycle bin
-R Restore selected files to the originalpath from rmtrash recycle bin
-l list the contens of rmtrash recycle bin
-i show detailed log of the deleted file history
-d delete one or more files by user's input file name from the trash
-e empty the rmtrash recycle bin
-h display this help menu
EOF
} ###rm mv function
rm_mv () {
echo ----------------------------
now=`date +%Y%m%d_%H:%M:%S`
dupfix=.`date +%Y%m%d%H%M%S`
###将用户输入的文件循环mv到trash中
###for file in $file_list ;do
#echo $file
###提取用户输入参数的文件名、目录名,拼出绝对路径
file_name=`basename $file`
file_dir=$(cd `dirname $file`;pwd)
file_fullpath=$file_dir/$file_name
###判断要删除的文件或者目录大小是否超过2G
#echo file_fullpath: $file_fullpath
#if [[ "$file_fullpath" == "/*" ]];then
# echo action deny!
#else
####判断即将删除的文件在trash目录里是否已存在
if [[ `ls $trash_dir|grep ^${file_name}$` ]];then
##已存在,文件名重复,需要rename,想原始名的基础上加后缀
trash_dest_path=$trash_dir$file_name$dupfix
echo trash目录里已存在$file_name,需要rename $file_name$dupfix
else
##不重名,直接按原始文件名保存
trash_dest_path=$trash_dir$file_name
fi ####判断如果是要删除文件是根目录,则直接提示并拒绝
if [[ "$file_name" == "/" ]];then
echo rm拒绝执行删除根目录操作,否则系统就挂了,你就悲剧了,请检查...
else
###mv成功记录log,记录删除时的文件、目录的路径等信息到log,以便恢复数据
mv $file_fullpath $trash_dest_path && \
echo $now `date +%s` `whoami` moved from $file_fullpath to $trash_dest_path >> $trash_log && \
echo -e "\033[31m\033[05m $file is deleted from $file_fullpath\033[0m"
#cat $trash_log
fi #fi
###done
} ###rm list function
rm_list () {
echo ----------------------------
echo list trash_dir contents:
ls $trash_dir
} ###rm restore function
rm_restore () {
echo ----------------------------
echo -en "请选择要恢复的文件名(多个文件中间空格分隔,取消ctl+c):"
read reply
for file in $reply ;do
###判断原始位置的是否有同名文件存在
originalpath=`cat $trash_log|grep /$file$|awk '{print $5}'`
if [[ `ls $originalpath` ]];then
echo -en "originalpath:$originalpath already exists. continue overwrite or not(y/n):"
read ack
if [[ $ack == y ]];then
echo restore:
elif [[ $ack == n ]];then
echo bye && exit
else
echo 输入非法 && exit
fi
fi
###
mv $trash_dir$file $originalpath && \
###linux和mac下sed的用法有细微差别,故需通过操作系统类型进行选择对应的sed格式
if [[ $os_type == Darwin ]];then
sed -i .bak "/\/$file$/d" $trash_log
echo os_type=Darwin
elif [[ $os_type == Linux ]];then
sed -i.bak "/\/$file$/d" $trash_log
echo os_type=Linux
fi && \
echo -e "\033[32m\033[05m$file restore ok to originalpath=$originalpath\033[0m"
done
} ### rm show delete log function
rm_infolog () {
echo ----------------------------
echo detailed deleted file log:
cat $trash_log
} ###rm empty trash function
rm_empty () {
echo ----------------------------
echo -en "empty trash,all backups in trash will be deleted, continue or not(y/n):"
read ack
if [[ $ack == y ]];then
echo begin to empty trash:
elif [[ $ack == n ]];then
echo bye && exit
else
echo 输入非法 && exit
fi
/bin/rm -fr ${trash_dir}* && \
echo >$trash_log && \
echo -e "\033[31m\033[05m The trash bin has been emptyed\033[0m"
} ###rm delete function
rm_delete () {
echo ----------------------------
echo -en "请选择trash中要删除的文件名(多个文件中间空格分隔,取消ctl+c):"
read reply
for file in $reply ;do
###if file exist then delete it from trash
if [[ `ls ${trash_dir}$file` ]];then
/bin/rm -fr ${trash_dir}$file && \
###linux和mac下sed的用法有细微差别,故需通过操作系统类型进行选择对应的sed格式
if [[ $os_type == Darwin ]];then
sed -i .bak "/\/$file$/d" $trash_log
echo os_type=Darwin
elif [[ $os_type == Linux ]];then
sed -i.bak "/\/$file$/d" $trash_log
echo os_type=Linux
fi && \
echo -e "\033[32m\033[05m$file is deleted from trash ${trash_dir}$file \033[0m"
else
echo $file is not exist in $trash_dir
fi
done
} ###清空回收站中30天之前执行rm删除过的文件
rm_delete_by_30_days () {
rm_mv_30_days_ago_timestamp=$
###**=
#30_days_by_seconds=
#cat $trash_log|awk 'BEGIN{30_days_by_seconds=2592000}{if()}'
awk 'END{
print 时间差:$-
{if ($->) print dayu}
}
' $trash_log
} ###跨分区的问题 #####主程序开始
###参数个数为0,输出help
if [ $# -eq ] ;then rm_usage ;fi
###根据用户输入选项执行相应动作
###通过非显示的方式(加入fr选项,但在case里不做匹配操作,遇到含-fr/-rf/-f/-r时直接删除)支持很多用户的使用习惯rm -fr file,rm -rf file
while getopts lRiecdhfr option ;do
case "$option" in
l) rm_list;;
R) rm_list
rm_restore;;
i) rm_infolog;;
h) rm_usage;;
e) rm_empty;;
c) rm_delete_by_30_days;;
d) rm_list
rm_delete;;
\?)rm_usage
exit ;;
esac
done
shift $((OPTIND-)) ###将文件名的参数依次传递给rm_mv函数
while [ $# -ne ];do
file=$
echo file=$file
rm_mv
shift
done
rmtrash
linux/mac下命令行rm回收站--rmtrash的更多相关文章
-
【转载】Linux系统下命令行连接蓝牙设备 查看查找 蓝牙
Linux系统下命令行连接蓝牙设备 2018年11月26日 10:47:27 Zz笑对一切 阅读数:741 1.打开系统蓝牙 sudo service bluetooth start 1 进入bl ...
-
Mac下命令行tree生成文件树
不像Windows,Mac环境本身是没有tree命令的,但可以后天呐~ 1.下载文件包并将其放在系统目录下(本人存放路径为/Users/) https://homebrew.bintray.com/b ...
-
在 Linux/windows下 命令行中使用和执行 PHP 代码[交互式php]
[注释]在ubuntu下,升级php到7.1版本,虽然提示的是Interactive mode enabled, 但实际上可以直接书写命令,和interactive shell效果一样. 一:wind ...
-
Mac下命令行中用sublime打开指定文件 设置方法
sublime2版本 官网提供的方法:sublime2 官网提供的方法是:ln -s "/Applications/Sublime Text 2.app/Contents/SharedSup ...
-
Mac下命令行批量重命名
日常中碰到需要批量修改文件名怎么办?嗯,来终端先 案例:将Users/case目录下所有html文件修改为php文件 步骤: 1.进入目标文件夹 $ cd Users/case 2.执行以下命令 $ ...
-
Mac下命令行下载android源代码并构建apk过程
前提是java .sdk.ndk .cmake.gradle .gradlew都已经安装和配置好. 1.下载源码: git clone http://git-ma.xxxx.com.cn/xxxx/x ...
-
java程序高CPU,如何直接定位(linux系统下命令行操作)
1.top命令找出 2.也可以使用 (1)ps -ef|grep java|grep -v grep (2)jps -l|grep 公司名 然后,记住PID是9529. 3.定位具体的线程或者代码: ...
-
mac下命令行安装node.js及切换不同版本nodejs
摘自: http://www.cnblogs.com/ikuyka/p/5825762.html 前提是你电脑里已经装了node.js然后才能采用以下命令(以下代码最好不要同时运行) sudo n - ...
-
Mac OSX系统、Linux、Windows命令行教程
目录 Mac OSX系统.Linux.Windows命令行教程 一.各系统终端的使用方法 二.各系统命令的功能 Mac OSX系统.Linux.Windows命令行教程 用你的终端做一些事情 (com ...
随机推荐
-
REMOVE ONCLICK DELAY ON WEBKIT FOR IPHONE
Developing on the webkit for iPhone I encountered a curious delay ononClick events. It seems that th ...
-
RDLC报表 在WinForm里运行出现 未能加载文件或程序集microsoft.reportviewer.winforms
做一下记录顺便帮助一下遇到问题的朋友. 做RDLC报表在WinForm运行,在VS里面调试引用了“Microsoft.ReportViewer.Common.dll”和“Microsoft.Repor ...
-
Python Paramiko模块
代码来自:http://www.cnblogs.com/wupeiqi/articles/4356675.html 今天学到了一个运维方面的利器:python的paramiko模块. paramiko ...
-
UVA 11354 Bond(MST + LCA)
n<=50000, m<=100000的无向图,对于Q<=50000个询问,每次求q->p的瓶颈路. 其实求瓶颈路数组maxcost[u][v]有用邻接矩阵prim的方法.但是 ...
-
jQuery Builder
简介 作用:customize jQuery,可以仅包含自己想要的模块 jQuery Builder lets you easily build a custom version of jQuery ...
-
bigdata_hive_Issue of Vectorization on Parquet table
When Vectorization is turned on in Hive:set hive.vectorized.execution.enabled=true;If the involved t ...
-
Treasure Hunt
Treasure Hunt time limit per test 1 second memory limit per test 256 megabytes input standard input ...
-
Java IO系列之一:IO
1. 概述 Java IO一般包含两个部分: 1.java.io包中堵塞型IO: 2.java.nio包中的非堵塞型IO,通常称为New IO. java.io包下,分为四大块近80个类: 1.基于字 ...
-
faiss索引基于数量级和内存限制的选择
它是一个能使开发者快速搜索相似多媒体文件的算法库.而该领域一直是传统的搜索引擎的短板.借助Faiss,Facebook 在十亿级数据集上创建的最邻近搜索(nearest neighbor search ...
-
132.leecode-Palindrome Partitioning II
这个题需要两个dp,一个保存从i到j是否为回文串 另一个保存0到i的最小的分割 下面是我的效率不太高的代码 class Solution { public: int minCut(string s) ...