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

源码如下:

  1. #!/bin/bash
  2. ### rmtrash,rm command line recycle bin for linux and mac osx.
  3. ### rmtrash 是linux和mac下命令行版本rm的回收站,安装后对用户透明,符合正常使用rm的习惯(支持rm -fr file哦),有了他再也不怕rm时候手颤抖了。
  4. ### 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.
  5. ### https://github.com/LaiJingli/rmtrash
  6. ### laijingli2006@gmail.com
  7. ### --
  8.  
  9. ###trash目录define
  10. realrm="/bin/rm"
  11. trash_dir=~/.rmtrash/
  12. trash_log=~/.rmtrash.log
  13. ###判断trash目录是否存在,不存在则创建
  14. if [ ! -d $trash_dir ] ;then
  15. mkdir -v $trash_dir
  16. fi
  17.  
  18. ###动态修改用户shell中的alias配置
  19. os_type=`uname`
  20. shell_path=$SHELL
  21. shell_type=`echo $SHELL|awk -F/ '{print $NF}'`
  22. alias_file=~/.${shell_type}rc
  23. alias_rm=`cat $alias_file|grep ^"alias rm="`
  24. return_value=$?
  25. #echo return_value: $return_value
  26. #echo alias_rm: $alias_rm
  27. ###如果不存在rm alias,则生成
  28. if [[ $return_value -ne ]] ;then
  29. echo first time to run rmtrash
  30. echo "alias rm=/bin/rmtrash.sh" >>$alias_file && source $alias_file
  31. ###如果存在rm alias,且不是指向rmtrash的,则注释掉,区分linux 和mac
  32. elif [[ "$alias_rm" != "alias rm=/bin/rmtrash.sh" ]];then
  33. echo already has alias rm,and must commit out
  34. if [[ $os_type == Darwin ]];then
  35. sed -i .bak 's/^alias\ rm=/#alias\ rm=/g' $alias_file && \
  36. echo "alias rm=/bin/rmtrash.sh" >>$alias_file && \
  37. source $alias_file
  38. elif [[ $os_type == Linux ]];then
  39. sed -i.bak 's/^alias\ rm=/#alias\ rm=/g' $alias_file && \
  40. echo "alias rm=/bin/rmtrash.sh" >>$alias_file && \
  41. source $alias_file
  42. fi
  43. fi
  44.  
  45. ####function define
  46. ###usage function
  47. rm_usage () {
  48. cat <<EOF
  49. Usage1: `basename $` file1 [file2] [dir3] [....] delete the files or dirs,and mv them to the rmtrash recycle bin
  50. Usage2: rm file1 [file2] [dir3] [....] delete the files or dirs,and mv them to the rmtrash recycle bin
  51. rm is alias to `basename $`.
  52. options:
  53. -f mv one or more files to the rmtrash recycle bin
  54. -r mv one or more files to the rmtrash recycle bin
  55. -fr mv one or more files to the rmtrash recycle bin
  56. -rf mv one or more files to the rmtrash recycle bin
  57. -R Restore selected files to the originalpath from rmtrash recycle bin
  58. -l list the contens of rmtrash recycle bin
  59. -i show detailed log of the deleted file history
  60. -d delete one or more files by user's input file name from the trash
  61. -e empty the rmtrash recycle bin
  62. -h display this help menu
  63. EOF
  64. }
  65.  
  66. ###rm mv function
  67. rm_mv () {
  68. echo ----------------------------
  69. now=`date +%Y%m%d_%H:%M:%S`
  70. dupfix=.`date +%Y%m%d%H%M%S`
  71. ###将用户输入的文件循环mv到trash中
  72. ###for file in $file_list ;do
  73. #echo $file
  74. ###提取用户输入参数的文件名、目录名,拼出绝对路径
  75. file_name=`basename $file`
  76. file_dir=$(cd `dirname $file`;pwd)
  77. file_fullpath=$file_dir/$file_name
  78. ###判断要删除的文件或者目录大小是否超过2G
  79. #echo file_fullpath: $file_fullpath
  80. #if [[ "$file_fullpath" == "/*" ]];then
  81. # echo action deny!
  82. #else
  83. ####判断即将删除的文件在trash目录里是否已存在
  84. if [[ `ls $trash_dir|grep ^${file_name}$` ]];then
  85. ##已存在,文件名重复,需要rename,想原始名的基础上加后缀
  86. trash_dest_path=$trash_dir$file_name$dupfix
  87. echo trash目录里已存在$file_name,需要rename $file_name$dupfix
  88. else
  89. ##不重名,直接按原始文件名保存
  90. trash_dest_path=$trash_dir$file_name
  91. fi
  92.  
  93. ####判断如果是要删除文件是根目录,则直接提示并拒绝
  94. if [[ "$file_name" == "/" ]];then
  95. echo rm拒绝执行删除根目录操作,否则系统就挂了,你就悲剧了,请检查...
  96. else
  97. ###mv成功记录log,记录删除时的文件、目录的路径等信息到log,以便恢复数据
  98. mv $file_fullpath $trash_dest_path && \
  99. echo $now `date +%s` `whoami` moved from $file_fullpath to $trash_dest_path >> $trash_log && \
  100. echo -e "\033[31m\033[05m $file is deleted from $file_fullpath\033[0m"
  101. #cat $trash_log
  102. fi
  103.  
  104. #fi
  105. ###done
  106. }
  107.  
  108. ###rm list function
  109. rm_list () {
  110. echo ----------------------------
  111. echo list trash_dir contents:
  112. ls $trash_dir
  113. }
  114.  
  115. ###rm restore function
  116. rm_restore () {
  117. echo ----------------------------
  118. echo -en "请选择要恢复的文件名(多个文件中间空格分隔,取消ctl+c):"
  119. read reply
  120. for file in $reply ;do
  121. ###判断原始位置的是否有同名文件存在
  122. originalpath=`cat $trash_log|grep /$file$|awk '{print $5}'`
  123. if [[ `ls $originalpath` ]];then
  124. echo -en "originalpath:$originalpath already exists. continue overwrite or not(y/n):"
  125. read ack
  126. if [[ $ack == y ]];then
  127. echo restore:
  128. elif [[ $ack == n ]];then
  129. echo bye && exit
  130. else
  131. echo 输入非法 && exit
  132. fi
  133. fi
  134. ###
  135. mv $trash_dir$file $originalpath && \
  136. ###linux和mac下sed的用法有细微差别,故需通过操作系统类型进行选择对应的sed格式
  137. if [[ $os_type == Darwin ]];then
  138. sed -i .bak "/\/$file$/d" $trash_log
  139. echo os_type=Darwin
  140. elif [[ $os_type == Linux ]];then
  141. sed -i.bak "/\/$file$/d" $trash_log
  142. echo os_type=Linux
  143. fi && \
  144. echo -e "\033[32m\033[05m$file restore ok to originalpath=$originalpath\033[0m"
  145. done
  146. }
  147.  
  148. ### rm show delete log function
  149. rm_infolog () {
  150. echo ----------------------------
  151. echo detailed deleted file log:
  152. cat $trash_log
  153. }
  154.  
  155. ###rm empty trash function
  156. rm_empty () {
  157. echo ----------------------------
  158. echo -en "empty trash,all backups in trash will be deleted, continue or not(y/n):"
  159. read ack
  160. if [[ $ack == y ]];then
  161. echo begin to empty trash:
  162. elif [[ $ack == n ]];then
  163. echo bye && exit
  164. else
  165. echo 输入非法 && exit
  166. fi
  167. /bin/rm -fr ${trash_dir}* && \
  168. echo >$trash_log && \
  169. echo -e "\033[31m\033[05m The trash bin has been emptyed\033[0m"
  170. }
  171.  
  172. ###rm delete function
  173. rm_delete () {
  174. echo ----------------------------
  175. echo -en "请选择trash中要删除的文件名(多个文件中间空格分隔,取消ctl+c):"
  176. read reply
  177. for file in $reply ;do
  178. ###if file exist then delete it from trash
  179. if [[ `ls ${trash_dir}$file` ]];then
  180. /bin/rm -fr ${trash_dir}$file && \
  181. ###linux和mac下sed的用法有细微差别,故需通过操作系统类型进行选择对应的sed格式
  182. if [[ $os_type == Darwin ]];then
  183. sed -i .bak "/\/$file$/d" $trash_log
  184. echo os_type=Darwin
  185. elif [[ $os_type == Linux ]];then
  186. sed -i.bak "/\/$file$/d" $trash_log
  187. echo os_type=Linux
  188. fi && \
  189. echo -e "\033[32m\033[05m$file is deleted from trash ${trash_dir}$file \033[0m"
  190. else
  191. echo $file is not exist in $trash_dir
  192. fi
  193. done
  194. }
  195.  
  196. ###清空回收站中30天之前执行rm删除过的文件
  197. rm_delete_by_30_days () {
  198. rm_mv_30_days_ago_timestamp=$
  199. ###**=
  200. #30_days_by_seconds=
  201. #cat $trash_log|awk 'BEGIN{30_days_by_seconds=2592000}{if()}'
  202. awk 'END{
  203. print 时间差:$-
  204. {if ($->) print dayu}
  205. }
  206. ' $trash_log
  207. }
  208.  
  209. ###跨分区的问题
  210.  
  211. #####主程序开始
  212. ###参数个数为0,输出help
  213. if [ $# -eq ] ;then rm_usage ;fi
  214. ###根据用户输入选项执行相应动作
  215. ###通过非显示的方式(加入fr选项,但在case里不做匹配操作,遇到含-fr/-rf/-f/-r时直接删除)支持很多用户的使用习惯rm -fr file,rm -rf file
  216. while getopts lRiecdhfr option ;do
  217. case "$option" in
  218. l) rm_list;;
  219. R) rm_list
  220. rm_restore;;
  221. i) rm_infolog;;
  222. h) rm_usage;;
  223. e) rm_empty;;
  224. c) rm_delete_by_30_days;;
  225. d) rm_list
  226. rm_delete;;
  227. \?)rm_usage
  228. exit ;;
  229. esac
  230. done
  231. shift $((OPTIND-))
  232.  
  233. ###将文件名的参数依次传递给rm_mv函数
  234. while [ $# -ne ];do
  235. file=$
  236. echo file=$file
  237. rm_mv
  238. shift
  239. 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. Machine Learning Trick of the Day (2): Gaussian Integral Trick

    Machine Learning Trick of the Day (2): Gaussian Integral Trick Today's trick, the Gaussian integral ...

  2. Java并发编程原理与实战二十八:信号量Semaphore

    1.Semaphore简介 Semaphore,是JDK1.5的java.util.concurrent并发包中提供的一个并发工具类. 所谓Semaphore即 信号量 的意思. 这个叫法并不能很好地 ...

  3. 【mybatis笔记】 resultType与resultMap的区别

    序言: 昨天做一个项目,看到很多刚开始用mybatis的同事对于resultType和resultMap的理解与使用含糊不清,这里我试图用最好理解的说法写一写,欢迎大家勘误. 两者异同: 相同点:re ...

  4. soj1763.传球游戏

    题目不算很难,dp的转移方程也很容易列出: 设dp[i][j] 代表第i次传球之后球回到j手中的传球数.易得: dp[i][j] = dp[i-1][j-1] + dp[i-1][j-1] 再处理一下 ...

  5. soj1767.传纸条

    这道题目想了一会儿觉得不知道如何下手,上网看了下资料,原来这道是一道非常经典的题目. 设 f [ k ][ i ][ j ] 表示第 k 步,第 1 条路径走到第 i 行,第 2 条路径走到第 j 行 ...

  6. soj1011. Lenny's Lucky Lotto

    1011. Lenny's Lucky Lotto Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description Lenny like ...

  7. 10个好用的JQuery代码片段收集

    1.预加载图片 (function($) { var cache = []; // Arguments are image paths relative to the current page. $. ...

  8. 让PHPCms内容页支持JavaScript_

    在PHPCms内容页中,出于完全考虑,默认是禁止JavaScript脚本的,所以我们在添加文章时,虽然加入了js代码,但实际上并没有起作用,而是以文本形式显示.如果要让内容页支持JavaScript, ...

  9. ADB常用命令(二)

    参考  http://adbshell.com/commands 常用命令 查看adb 版本 adb version 打印所有附加模拟器/设备的列表 adb devices 设备序列号 adb get ...

  10. 关于Unity启动时间过长(启动黑屏时间长)的问题!!! 牛逼... 思路不错...

    http://blog.csdn.net/u012169685/article/details/52068809