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 ...
随机推荐
- Java获取精确到秒的时间戳
1.时间戳简介: 时间戳的定义:通常是一个字符序列,唯一地标识某一刻的时间.数字时间戳技术是数字签名技术一种变种的应用.是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01 ...
- Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第四部分(Page 9)
编写你的第一个 Django app,第四部分(Page 9)转载请注明链接地址 该教程上接前面的第三部分.我们会继续开发 web-poll 应用,并专注于简单的表单处理和简化代码. 写一个简单的表单 ...
- Jekens Source Code Management None 源码管理没有Git
jekens安装完成后,在配置中Source Code Management没有Git的选项,只有none,搞了大半天,一直安装插件报错,网上找的各种文章均未能解决我的问题,多次尝试后终于解决了这个问 ...
- 详细讲解安全升级MySQL的方法
MySQL升级是非常必要的. 我们在Percona Support上列出了关于MySQL升级最佳实践的各种问题.这篇文章推荐了一些不同情况下升级MySQL的方法. 为什么MySQL升级是必须的? 原因 ...
- [转]天才计算机程序员 -- fabrice bellard
这位老兄就是用javascript写linux的那位,他的主页是:http://bellard.org/ 上面有他的几个作品,包括qemu,ffmpeg,tcc等. 这个世界从来不缺天才,只缺乏利用天 ...
- [csp-201509-3]模板生成系统
#include<bits/stdc++.h> using namespace std; ; string a[N],b[N],c[N]; int main() { //freopen(& ...
- 用代码从文件中导入数据到SQL Server
引言 导入数据到SQL Server 是常见的需求,特别是定期导入这种需求. 对于定期导入主要有以下几种方式可选择: Bulk Insert Bcp Utility OpenRowSet 写程序导入( ...
- Servlet笔记3--Servlet生命周期
Servlet生命周期:
- oracle 修改属性
alter table 表名 modify 字段名 类型; alter table 表名 modify 字段名 属性名; alter table TEST modify sbirthday not n ...
- avalonJS-源码阅读(一)
写angularJS源码阅读系列的时候,写的太垃圾了.一个月后看,真心不忍直视,以后有机会的话得重写.这次写avalonJS,希望能在代码架构层面多些一点,少上源码.多写思路. avalon暴露句柄方 ...