linux/mac下命令行rm回收站--rmtrash
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的更多相关文章
- 【转载】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 ...
随机推荐
- WPF控件收集
1.Extended WPF Toolkit 2.Fluent Ribbon Control Suite 3.WPF Ribbon Control 4.Telerik RadControls for ...
- 【译】第五篇 Integration Services:增量加载-Deleting Rows
本篇文章是Integration Services系列的第五篇,详细内容请参考原文. 在上一篇你学习了如何将更新从源传送到目标.你同样学习了使用基于集合的更新优化这项功能.回顾增量加载记住,在SSIS ...
- Linux环境下如何查看内存CPU和GPU使用情况以及界面标题栏实现
查看内存和CPU 单独查看内存使用情况的命令:free -m 查看内存及cpu使用情况的命令:top 也可以安装htop工具,这样更直观, 安装命令如下:sudo apt-ge ...
- WeX5入门之HelloWorld
学习目标:数据双向绑定 在ui2上右键 新建一个应用 然后会出现一个目录 右键hello 在创建页面 选择标准的空白模板 并起一个名 自动生成这两个文件 建立一个input组件 再建一个output组 ...
- 【矩阵】RQ/QR 分解
Multiple View Geometry in Computer Vision A.4.1.1 (page 579) 将一个 3x3 矩阵 $ A $ 进行 RQ 分解是将其分解成为一个上三角阵 ...
- Hibernate5笔记3--详解Hibernate的API
详解Hibernate的API: (1)Configuration接口: org.hibernate.cfg.Configuration接口的作用是加载主配置文件及映射文件,以实现对Hibernate ...
- android开发中常用的快捷键
Eclipse快捷键-方便查找,呵呵,记性不好 行注释/销注释 Ctrl+/ 块注释/销注释/XML注释 Ctrl+Shift+/ Ctrl+Shift+\查找 查找替换 Ctrl+H Ctr ...
- avalonJS-源码阅读(一)
写angularJS源码阅读系列的时候,写的太垃圾了.一个月后看,真心不忍直视,以后有机会的话得重写.这次写avalonJS,希望能在代码架构层面多些一点,少上源码.多写思路. avalon暴露句柄方 ...
- ArcGIS RunTime Sdk +WPF 基础地图显示
1 简单的地图展示 ArcGISRunTime 的平面地图展示主要依赖MapView这个控件,MapView是地图的容器,Map主要是图层的集合 (注:三维场景的显示主要依赖SceneView这个控件 ...
- Python爬虫之三种网页抓取方法性能比较
下面我们将介绍三种抓取网页数据的方法,首先是正则表达式,然后是流行的 BeautifulSoup 模块,最后是强大的 lxml 模块. 1. 正则表达式 如果你对正则表达式还不熟悉,或是需要一些提 ...