首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不允许` to‘移除`*’

不允许` to‘移除`*’
EN

Code Review用户
提问于 2019-03-09 02:32:08
回答 5查看 208关注 0票数 9

注意:如果你在谷歌上搜索这个问题的标题,除非你知道它应该做什么,否则不要使用这个脚本。

这是bash 3+中的一个脚本,用于防止rm *rm -rf *意外调用和错误删除重要文件。我把它放在我的~/.bash_aliases里。

代码语言:javascript
复制
alias rm='set -f;rm'
rm(){
    if [[ "$-" == *i* ]]
    then
        if [ "$1" = "*" ] || [ "$2" = "*" ] || [ "$1" = "./*" ] || [ "$2" = "./*" ]
        then
            echo "Abort: refusing to remove *, please go to the parent folder and do rm /*" 1>&2
            set +f
            return 1
        fi
    fi  
    set +f
    /bin/rm -i $@
}

set +f

我想知道是否有任何漏洞,是否可以改进。

EN

回答 5

Code Review用户

发布于 2019-03-09 03:18:06

我看到的漏洞是,只检查前两个参数。你可以检查所有这些:

代码语言:javascript
复制
rm() { 
    [[ $- == *i* ]] && for arg
    do 
        if [[ $arg = "*" || $arg = "./*" ]]
        then
            # abort
       fi
   done
   # do the rm

这种检查将错过其他危险的通配符,如**?*。您可以通过自己展开*来获得更安全的检查,然后查看展开的参数是否包含相同的文件列表:

代码语言:javascript
复制
# alias not needed here; we want globs to be expanded
rm() {
    declare -a star=(*)
    declare -a dotslashstar=(./*)
    if [[ "$@" == *"${star[@]}"*  ||  "$@" == *"${dotslashstar[@]}"* ]]
    then
         # abort

..。但是,如果rm *.tmp*匹配,那么就不能(例如)用*.tmp来清空满是临时文件的目录。

票数 11
EN

Code Review用户

发布于 2019-03-09 12:37:20

双引号变量用于命令参数

这是一个bug:

/bin/rm -i $@

如果您尝试删除文件a b (名称中有空格),会发生什么情况?最有可能的是:

rm: a:没有这样的文件或目录,rm: b:没有这样的文件或目录。

始终编写"$@"而不是未引用的$@

不幸的是,正如您在评论中指出的那样,这将导致另一个问题:包含全局的参数将被视为字面意思。总之,吃蛋糕也很难。

您可以通过遍历参数来缓解这个问题,如果您检测到一个glob,那么自己展开它:

代码语言:javascript
复制
for arg; do
    if [[ $arg == *[*?]* ]]; then
        expanded=($arg)
        echo rm -i "${expanded[@]}"
    else
        echo rm -i "$arg"
    fi
done

这仍然不是完美的,因为当参数同时包含空格和全局时,它不会处理这种情况。一个健壮的解决方案将需要更多的努力,而不值得在Bash中进行。(请参见将艰苦工作委托给Python的这个例子。)

使用command绕过别名

不要担心命令的绝对路径。使用command绕过别名:

代码语言:javascript
复制
command rm -i "$@"

冗余文件描述符

echo "Abort: ..." 1>&2中,文件描述符1是多余的,您可以安全地省略它。

保护用户环境

这是个小小的挑剔。当别名被执行时,它将执行set +f,而不管shell中的原始设置是什么,这可能是不一样的。这真的只是一个小小的挑剔,作为记录。我也不会在乎这些不切实际的细节。

票数 8
EN

Code Review用户

发布于 2019-03-11 10:17:29

不要调用您的函数rm

如果您开始依赖于这个安全网,那么您最终将在一个具有标准rm的系统上发生事故(例如,当您成为root用户并发现自己在管理任务中使用dash时)。

我建议

代码语言:javascript
复制
weijun_rm() {
    # your safer implementation
}

rm() {
     echo "Disabled - please use weijun_rm instead" >&2
     return 1
}

这将训练您不要使用rm来删除文件。当您的函数不可用并且必须使用真正的rm时,您将保持警惕,并格外小心地检查参数。

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/215069

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档