ash 是否有相当于 bash 的“nullglob”选项?

问题描述 投票:0回答:2

如果 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
~ # 
bash shell scripting shopt
2个回答
6
投票

此方法比每次迭代检查是否存在更高效:

set -- nonexistent-file-*
[ -e "$1" ] || shift
for filename; do
    echo "$filename"
done

我们使用

set
将通配符扩展到 shell 的参数列表中。请注意,这将覆盖最初传递给脚本的任何位置参数(
$1
$2
,...)。即使 glob 模式以
--
+
字符开头(可能与其他
-
用法发生冲突),特殊参数
set
也可以使其正常工作。

如果参数列表的第一个元素不存在,则 glob 不匹配任何内容。与将第一个结果与逐字 glob 模式进行比较不同,即使 glob 的第一个匹配项与 glob 模式相同的文件名也可以正常工作。

如果不匹配,则参数列表包含单个元素,我们将其移走,以便参数列表现在为空。那么

for
循环根本不会执行任何迭代。

否则,当变量名后面没有任何内容时,我们会使用

for
的隐式行为循环遍历 glob 扩展成的参数列表(相当于
in "$@"
,迭代所有位置参数)。


5
投票

对于没有

nullglob
的外壳,例如 ash 和 dash:

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 中的文件名和路径名:如何正确执行缓存

© www.soinside.com 2019 - 2024. All rights reserved.