在某次产品升级中,在A机器删除了data目录,后续重新创建,原B机器挂载了A机器的data目录,导致B机器df -h没有反应。后续做数据库主从的步骤中,对B机器进行了重启操作,B机器一直启动不成功,因为加载data共享卷的时候找不到data卷,需要在B机器/etc/fstab注释共享卷的引用。此时A、B机器均没有正式投入使用。
为了避免后续类似事情发生,需要对rm命令做一定的限制。

  1. 需要设定某些目录不能删除。
  2. 最好不是真正删除,而是移除。

本来想用现成的safe-rm来解决,但是safe-rm只是做了确认操作,并不满足条件,还是需要修改脚本。那就直接来写一个脚本然后做alias操作,来做个伪rm。
脚本如下:

#!/bin/bash


DT=`date +%Y%m%d_%H%M%S`
mkdir -p ~/.trash
RED='\E[1;31m'
RES='\E[0m'
GREEN='\E[1;32m'
#设置保护目录
savePaths=(/app /app/systems/ezdeploy/data /app/ezdeploy/data /tmp/data)
orgPaht=`pwd`
for i in $*
do
    if [[ "$i" == "-rf" || "$i" == "-r" || "$i" == "-f" ]]
    then
        continue
    fi
    if [ ! -e $i ]
    then
        echo $i 不存在
        exit 1
    fi
    allowToRemove=1
    filePath=$i
    if [ -d $i ]
    then
        filePath=$(cd "$i";pwd)
    fi
    cd $orgPaht
    for savePath in ${savePaths[@]}
    do
        if [ $filePath == $savePath ]
        then
            echo 0 >/dev/null
            allowToRemove=0
        else
            echo 1 >/dev/null
        fi
    done
    echo ===============================
    if [ $allowToRemove == 1 ]
    then
        if `mv $i ~/.trash/$i"_"$DT`
        then
            echo -e "${GREEN}$i 已经删除${RES}"
        else
            echo -e "${RED}发生错误,请检查${RES}"
            exit 1
        fi
    else
        echo -e "${RED}$i 不允许删除${RES}"

    fi
done

把执行rm操作变成mv操作,放到~./trash底下,加上时间戳后缀,避免重复;
对rm命令的常用option做规避操作。
需要注意一点的是执行过程中的各种报错信息,可能导致最后的mv失败,尽量避免。
染色也有点意思,\E[5;31m代表跳动的红色,还有各种各样的颜色和背景色,感觉还是不要太花哨了。

执行:
alias rm=‘/app/ezdeploy/tools/remove.sh’
并将这个条命令加到~/.bash_profile中
对trash做定时清理操作:
crontab -e
0 0 * * * rm -rf ~/.trash

效果图:

image-1655096209540

Q.E.D.


知之为知之