使用 shell 来定义更安全的 rm

摘要: 本文将介绍通过使用简单的 shell 脚本来代替使用 rm 命令。

rm -rf / 经常大家用来与 Linux/Unix 小白来开玩笑,然而实际上如果真的操作不当,在生产服务器上执行了它,在没有备份的情况下,还是很容易造成严重后果。如果你对 rm -rf / 这样“删库跑路”般的操作感到恐惧,那么重新定义你的 rm 是一个不错的选择。

于是就写了一个 shell 脚本 Easy-Trash,它基于 mv 命令,支持移入回收站、查看回收站、清空回收站、从回收站恢复等操作。测试下来,因为基于 Linux/Unix 自带的 mv 命令,它的效率是非常高效的。

之前有使用过 python 版的 trash-cli ,体验下来的结果是在删除大量文件和大文件的时候,效率并不高。

与之类似,Easy-Trash 使用同样的思路,在 Linux/Unix 上自定义一个 .trash 目录作为回收站,删除实际上是将需要删除的文件移动到回收站当中,一旦误删,则可以从回收站恢复文件,它同时支持 bashzsh

Easy-Trash 项目地址:
https://github.com/ZitherPeng/Easy-Trash

安装

在 Linux 上

复制下面的内容追加到 /etc/profile(所有用户有效)~/.bashrc~/.zshrc (只有当前有效)。

# add trash function
mkdir -p ~/.trash
alias rm='echo "This is not the command you are looking for, Please Use "trash"!!!"; false'
alias trash-list='ls -la ~/.trash'
alias trash-restore=undelfile
alias trash-empty=cleartrash

trash(){
  for filename in $@
  do
    # 判断 .trash 目录中的已有文件,如果存在则加上时间戳后缀
    if [ -n "`find ~/.trash -maxdepth 1 -name ${filename}`" ]
    then
    mv ${filename} ~/.trash/${filename}_`date +%Y%m%d-%H%M%S`
    else
    mv ${filename} ~/.trash/
    fi
  done
}

cleartrash(){
  # 兼容 bash、zsh、bash 中启动的 zsh、zsh 中启动的 bash
  if [[ $SHELL =~ 'zsh' ]]
  then
    if [[ $0 =~ 'bash' ]]
    then 
    read -p "clear sure?[y/n] " confirm
    else
    vared -p "clear sure?[y/n] " -c confirm
    fi
  elif [[ $SHELL =~ 'bash' ]]
  then
  read -p "clear sure?[y/n]" confirm
  fi
  # 同时删除清空 .trash 目录中的隐藏文件和非隐藏文件
  [ $confirm = 'y' ] || [ $confirm = 'Y' ]  && /bin/rm -rf ~/.trash/*  && find ~/.trash/ -mindepth 1 -name '.*' | xargs /bin/rm -rf
}

undelfile(){
  mv -i ~/.trash/$@ ./
}

在 MacOS 上

在 MacOS 中可直接使用系统自带的 .Trash 废纸篓目录,达到命令行和图形界面的垃圾桶两桶合一。
将下面的代码附加到文件 /etc/profile(所有用户有效,但不推荐),或者 ~/.bash_profile~/.zshrc (只有当前用户有效)。

# add trash function using graphical interface .Trash
alias rm='echo "This is not the command you are looking for, Please Use "trash"!!!"; false'
alias trash-list='ls -la ~/.Trash'
alias trash-restore=undelfile
alias trash-empty=cleartrash

trash(){
  for filename in $@
  do
    if [ -n "`find ~/.Trash -maxdepth 1 -name ${filename}`" ]
    then
    mv ${filename} ~/.Trash/${filename}_`date +%Y%m%d-%H%M%S`
    else
    mv ${filename} ~/.Trash/
    fi
  done
}

cleartrash(){
  if [[ $SHELL =~ 'zsh' ]]
  then
    if [[ $0 =~ 'bash' ]]
    then 
    read -p "clear sure?[y/n] " confirm
    else
    vared -p "clear sure?[y/n] " -c confirm
    fi
  elif [[ $SHELL =~ 'bash' ]]
  then
  read -p "clear sure?[y/n]" confirm
  fi
  [ $confirm = 'y' ] || [ $confirm = 'Y' ]  && /bin/rm -rf ~/.Trash/*  && find ~/.Trash/ -mindepth 1 -name '.*' | xargs /bin/rm -rf
}

undelfile(){
  mv -i ~/.Trash/$@ ./
}

如何使用

trash [file ...]              # 移动到垃圾桶
trash-restore [file ...]      # 从垃圾桶恢复文件
trash-list                    # 显示垃圾桶中的文件
trash-empty                   # 清空垃圾桶

e.g. 简单演示

Tips:本站使用 Disqus 评论,被墙访客请科学上网后点击加载。