当没有文件时,遍历文件会产生奇怪的结果

Iterating through files gives odd results when no files

我正在尝试遍历 bash 脚本中的所有 zip 文件(我使用的是 Cygwin,但我有点怀疑这是 Cygwin 的错误)。

现在看起来像这样:

for z in *.zip
do
    echo $z
done

当文件夹中有 zip 文件时效果很好,它会完全回显 zip 文件,只回显 zip 文件。但是,当我在一个空的文件夹上执行此操作时,它会回显 *.zip,而我宁愿它什么也不回显。

我应该做什么?我不认为正确的解决方案是 if [ $z != "*.zip ]...但是是吗?

或者打开 nullglob 选项。

$ set -x
$ echo *.none
+ echo '*.none'
*.none
$ shopt -s nullglob
+ shopt -s nullglob
$ echo *.none
$ echo *.none
+ echo

作为执行命令的步骤之一,shell可能会执行路径扩展,在这种情况下它将替换字符串,例如*.zip 与匹配该 glob 的文件列表。 如果没有这样的文件,则字符串保持不变。合理的解决方案是:

for z in *.zip
do
    [ -f "$z" ] && echo $z
done

[ -f "$z" ] 验证文件是否存在并且是一个普通文件。 && 意味着 echo 只有在该测试通过后才会执行。

这是预期的行为。来自 documentation:

If no matching filenames are found, and the shell option nullglob is disabled, the word is left unchanged. If the nullglob option is set, and no matches are found, the word is removed.

所以解决方法是在循环之前设置nullglob选项:

shopt -s nullglob
for z in *.zip
    ...