Ash是否有类似于Bash的“nullglob”选项的等效选项?

8
如果一个 glob 模式没有匹配到任何文件,bash 将会返回字面上的模式。
bash-4.1# echo nonexistent-file-*
nonexistent-file-*
bash-4.1#

您可以通过设置 nullglob shell 选项来修改默认行为,因此如果没有匹配项,您将得到一个空字符串:

bash-4.1# shopt -s nullglob
bash-4.1# echo nonexistent-file-*

bash-4.1# 

那么,在ash中有相应的选项吗?
bash-4.1# ash
~ # echo nonexistent-file-*
nonexistent-file-*
~ # shopt -s nullglob
ash: shopt: not found
~ # 
2个回答

5

对于没有像ash和dash这样的nullglob的shell:

IFS="`printf '\n\t'`"   # Remove 'space', so filenames with spaces work well.

# Correct glob use: always use "for" loop, prefix glob, check for existence:
for file in ./* ; do        # Use "./*", NEVER bare "*"
    if [ -e "$file" ] ; then  # Make sure it isn't an empty match
        COMMAND ... "$file" ...
    fi
done

来源:Shell中的文件名和路径名:正确使用方法缓存


3
我认为在这种情况下,你不需要设置IFS。 - drizzt
1
这仅适用于恰好匹配自身的通配符。它不是 nullglob 的通用替代方案。 - that other guy
它使用 test "$(echo file-*)" = "file-*" && true || <something using files> 解决了这个问题。 - Mattias Wadman

5

这种方法比每次迭代检查存在性更高效:

set q-*
[ -e "$1" ] || shift
for z; do echo "$z"
done

我们使用set将通配符扩展为shell的参数列表。如果参数列表的第一个元素不是有效文件,则通配符没有匹配任何内容。(与某些常见尝试不同,即使通配符的第一个匹配项是与通配符模式相同的文件名,这也可以正确地工作。)
如果没有匹配项,则参数列表包含一个单独的元素,我们将其移除,以便参数列表现在为空。然后,for循环将不执行任何迭代。
否则,我们循环遍历通配符扩展成的参数列表(当for variable后面没有in elements时,这是隐式行为)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接