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

原文地址: http://blog.csdn.net/xuyaqun/article/details/44306055

源码如下:

#!/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的更多相关文章

  1. 【转载】Linux系统下命令行连接蓝牙设备 查看查找 蓝牙

    Linux系统下命令行连接蓝牙设备 2018年11月26日 10:47:27 Zz笑对一切 阅读数:741   1.打开系统蓝牙 sudo service bluetooth start 1 进入bl ...

  2. Mac下命令行tree生成文件树

    不像Windows,Mac环境本身是没有tree命令的,但可以后天呐~ 1.下载文件包并将其放在系统目录下(本人存放路径为/Users/) https://homebrew.bintray.com/b ...

  3. 在 Linux/windows下 命令行中使用和执行 PHP 代码[交互式php]

    [注释]在ubuntu下,升级php到7.1版本,虽然提示的是Interactive mode enabled, 但实际上可以直接书写命令,和interactive shell效果一样. 一:wind ...

  4. Mac下命令行中用sublime打开指定文件 设置方法

    sublime2版本 官网提供的方法:sublime2 官网提供的方法是:ln -s "/Applications/Sublime Text 2.app/Contents/SharedSup ...

  5. Mac下命令行批量重命名

    日常中碰到需要批量修改文件名怎么办?嗯,来终端先 案例:将Users/case目录下所有html文件修改为php文件 步骤: 1.进入目标文件夹 $ cd Users/case 2.执行以下命令 $ ...

  6. Mac下命令行下载android源代码并构建apk过程

    前提是java .sdk.ndk .cmake.gradle .gradlew都已经安装和配置好. 1.下载源码: git clone http://git-ma.xxxx.com.cn/xxxx/x ...

  7. java程序高CPU,如何直接定位(linux系统下命令行操作)

    1.top命令找出 2.也可以使用 (1)ps -ef|grep java|grep -v grep (2)jps -l|grep  公司名 然后,记住PID是9529. 3.定位具体的线程或者代码: ...

  8. mac下命令行安装node.js及切换不同版本nodejs

    摘自: http://www.cnblogs.com/ikuyka/p/5825762.html 前提是你电脑里已经装了node.js然后才能采用以下命令(以下代码最好不要同时运行) sudo n - ...

  9. Mac OSX系统、Linux、Windows命令行教程

    目录 Mac OSX系统.Linux.Windows命令行教程 一.各系统终端的使用方法 二.各系统命令的功能 Mac OSX系统.Linux.Windows命令行教程 用你的终端做一些事情 (com ...

随机推荐

  1. WPF控件收集

    1.Extended WPF Toolkit 2.Fluent Ribbon Control Suite 3.WPF Ribbon Control 4.Telerik RadControls for ...

  2. 【译】第五篇 Integration Services:增量加载-Deleting Rows

    本篇文章是Integration Services系列的第五篇,详细内容请参考原文. 在上一篇你学习了如何将更新从源传送到目标.你同样学习了使用基于集合的更新优化这项功能.回顾增量加载记住,在SSIS ...

  3. Linux环境下如何查看内存CPU和GPU使用情况以及界面标题栏实现

    查看内存和CPU    单独查看内存使用情况的命令:free -m    查看内存及cpu使用情况的命令:top    也可以安装htop工具,这样更直观,    安装命令如下:sudo apt-ge ...

  4. WeX5入门之HelloWorld

    学习目标:数据双向绑定 在ui2上右键 新建一个应用 然后会出现一个目录 右键hello 在创建页面 选择标准的空白模板 并起一个名 自动生成这两个文件 建立一个input组件 再建一个output组 ...

  5. 【矩阵】RQ/QR 分解

    Multiple View Geometry in Computer Vision A.4.1.1 (page 579) 将一个 3x3 矩阵 $ A $ 进行 RQ 分解是将其分解成为一个上三角阵 ...

  6. Hibernate5笔记3--详解Hibernate的API

    详解Hibernate的API: (1)Configuration接口: org.hibernate.cfg.Configuration接口的作用是加载主配置文件及映射文件,以实现对Hibernate ...

  7. android开发中常用的快捷键

    Eclipse快捷键-方便查找,呵呵,记性不好 行注释/销注释 Ctrl+/  块注释/销注释/XML注释 Ctrl+Shift+/   Ctrl+Shift+\查找 查找替换 Ctrl+H  Ctr ...

  8. avalonJS-源码阅读(一)

    写angularJS源码阅读系列的时候,写的太垃圾了.一个月后看,真心不忍直视,以后有机会的话得重写.这次写avalonJS,希望能在代码架构层面多些一点,少上源码.多写思路. avalon暴露句柄方 ...

  9. ArcGIS RunTime Sdk +WPF 基础地图显示

    1 简单的地图展示 ArcGISRunTime 的平面地图展示主要依赖MapView这个控件,MapView是地图的容器,Map主要是图层的集合 (注:三维场景的显示主要依赖SceneView这个控件 ...

  10. Python爬虫之三种网页抓取方法性能比较

    下面我们将介绍三种抓取网页数据的方法,首先是正则表达式,然后是流行的 BeautifulSoup 模块,最后是强大的 lxml 模块. 1. 正则表达式   如果你对正则表达式还不熟悉,或是需要一些提 ...