Bash * 目录通配符在使用双括号的 if 语句中不起作用

Bash * 目录通配符在使用双括号的 if 语句中不起作用

这有效:

if  [ /a/*/b/file.asd -nt  /c/d/file.asd ]; then echo "found new file"; fi

这不起作用:

if  [[ /a/*/b/file.asd -nt  /c/d/file.asd ]]; then echo "found new file"; fi

有人可以解释一下为什么/*/不使用双括号吗?

答案1

Shell 通配模式可能会扩展到多个路径名。例如,如果/a/*/b/file.asd扩展到多个路径名,那么您正在执行的测试就变得毫无意义。

此外,shell glob 是不是里面扩大了[[ ... ]]。从bash手册:

不对[[和之间的单词执行分词和路径名扩展]]

如果您知道要在特别的文件,例如/a/x/b/file.asd,然后在测试中使用该路径名。如果您想执行测试全部与该模式匹配的路径名,使用循环:

shopt -s nullglob dotglob
for pathname in /a/*/b/file.asd; do
    if [[ $pathname -nt /c/d/file.asd ]]; then
        printf 'found new file: %s\n' "$pathname"
    fi
done

设置nullglobdotglobshell 选项,以便在模式不匹配任何内容时将其删除,并*捕获任何隐藏目录。

此外,测试可以使用 完成find,除非模式/a/*/b/file.asd扩展到数千个路径名:

find /a/*/b/file.asd -prune -type f -newer /c/d/file.asd

这将扩展模式/a/*/b/file.asd并使用它扩展为的每个路径名作为 的搜索路径find。测试搜索路径/c/d/file.asd,如果路径名比该文件新,则打印路径名。停止向下移动到搜索路径,以防万一它们中-prunefind任何一个引用目录。

相关内容