网上铺天盖地的说rm命令危险,但是真正想限制rm命令时,发现一个能用的解决方案都没有。常规做法是新建一个trash目录,把删除的内容mv到这个目录,在定期清理这个目录。思路是一样的,我自己动基于alias写了个脚本来限制rm命令,有以下好处:

  1. 只有一个脚本批量部署非常方便,不需求安装第三方软件
  2. 每次删除时会提示删除的内容,删除是将要移除的文件mv到/tmp/.trash/当天日期下,同时会提示是否清理目录,相当于做了double check
  3. 限制删除内容:只允许删除文件和目录,对于特殊的软链接、设备等文件默认不允许删除
    其它功能懒得写了,使用方法将脚本丢到/etc/profile.d/即可。
#!/bin/bash
#author: will
#website: https://www.nixops.me

rm_cmd(){

arg_array=()
for var in $*
do
    if [ ! `echo "$var" |grep "^-"` ];then
      arg_array+=("$var")      
    fi 
done 

if [ "$#" -eq "0" ] ;then
    echo -e "\e[00;32mYou Are Using Security \"rm\" command \e[00m"
    return 0
elif [ ${#arg_array[@]} -eq 0 ];then
    echo -e "\e[00;32mYou Are Using Security \"rm\" command \e[00m"
    return 0
fi

echo -e "\033[00;31mYou are going to DELETE:  \033[00m"

list_array=()
for element in ${arg_array[@]}
do
   if [ -f $element ];then
       echo FILE: $element 
       list_array+=("$element")
   elif [ -d $element ];then 
       echo DIR: $element 
       list_array+=("$element")
   elif [ -S $element ];then 
       echo -e "\e[00;32mSOCKET: $element NOT Allow To Delete\e[00m"
       return 0 
   elif [ -p $element ];then 
       echo -e "\e[00;32mPIPE: $element NOT Allow To Delete\e[00m"
       return 0 
   elif [ -b $element ];then 
       echo -e "\e[00;32mBLOCK DEVICE: $element NOT Allow To Delete\e[00m"
       return 0 
   elif [ -c $element ];then 
       echo -e "\e[00;32mCHARACTER DEVICE: $element NOT Allow To Delete\e[00m"
       return 0 
   else
       echo -e "\e[00;32mNOT Exist: $element \e[00m"
       return 0 
   fi
done

read -n1 -p $'\033[00;31mAre you sure to DELETE [Y/N]? ' answer
case $answer in
Y | y)
      echo -e "\n"

      if [ ! -d "/tmp/.trash/`date -I`" ]; then
        mkdir -p /tmp/.trash/`date -I`
        chmod 777 /tmp/.trash/`date -I`
      fi

      for element in ${list_array[@]}
      do 
        echo -e "Deleting $element to /tmp/.trash/`date -I`"
        #/bin/rm --preserve-root     -rf  $element
        
        mv $element /tmp/.trash/`date -I`

        if [ $? -ne "0" ];then
          echo -e "\nDeleted FAILED"
          return 0
        fi
      done
      echo -e "\nDeleted FINISHED"

      read -n1 -p $'\033[00;31mFree Disk Space ?  [Y/N]? ' fanswer
      case $fanswer in

      Y | y)
          /bin/rm --preserve-root -rf /tmp/.trash/*
          echo -e "\n"
      ;;
      *)
          echo -e "\nFree Disk Space SKIPED"
          echo -e "\n"
      ;;
      esac
;;
*)
      echo -e "\nDelete SKIPED"
;;

esac
}

alias rm='rm_cmd $@'
alias grep='grep --color=auto'
alias cp='cp -i'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'