这个问题类似于在 *nix 中清空目录最安全的方法是什么?
我正在编写 bash 脚本,它定义了几个路径常量,并将它们用于文件和目录操作(复制、重命名和删除)。通常有必要执行以下操作:
rm -rf "/${PATH1}"
rm -rf "${PATH2}/"*
在开发此脚本时,我想保护自己免受 PATH1 和 PATH2 之类的错误输入名称的影响,并避免将它们扩展为空字符串的情况,从而导致擦除整个磁盘。我决定创建特殊的包装器:
rmrf() {
if [[ $1 =~ "regex" ]]; then
echo "Ignoring possibly unsafe path ${1}"
exit 1
fi
shopt -s dotglob
rm -rf -- $1
shopt -u dotglob
}
这将被称为:
rmrf "/${PATH1}"
rmrf "${PATH2}/"*
正则表达式(或 sed 表达式)应捕获诸如“*”、“/*”、“/**/”、“///*”等路径,但允许诸如“dir”、“/dir”、“/dir1”之类的路径/dir2/"、"/dir1/dir2/*"。此外,我不知道如何在“/dir with space/*”之类的情况下启用 shell globbing。有任何想法吗?
编辑:这是我到目前为止想出的:
rmrf() {
local RES
local RMPATH="${1}"
SAFE=$(echo "${RMPATH}" | sed -r 's:^((\.?\*+/+)+.*|(/+\.?\*+)+.*|[\.\*/]+|.*/\.\*+)$::g')
if [ -z "${SAFE}" ]; then
echo "ERROR! Unsafe deletion of ${RMPATH}"
return 1
fi
shopt -s dotglob
if [ '*' == "${RMPATH: -1}" ]; then
echo rm -rf -- "${RMPATH/%\*/}"*
RES=$?
else
echo rm -rf -- "${RMPATH}"
RES=$?
fi
shopt -u dotglob
return $RES
}
预期用途是(注意引号内的星号):
rmrf "${SOMEPATH}"
rmrf "${SOMEPATH}/*"
其中 $SOMEPATH 不是系统或 /home 目录(在我的情况下,所有此类操作都是在 /scratch 目录下安装的文件系统上执行的)。
注意事项:
- 没有很好地测试
- 不打算与可能包含“..”或“.”的路径一起使用
- 不应与用户提供的路径一起使用
- 如果 $SOMEPATH 中的文件或目录过多(由于命令行长度有限),带有星号的 rm -rf 可能会失败 - 这可以通过“for”循环或“find”命令修复