bash for循环没有文件

Jav*_*Jav 4 bash for-loop wildcard shopt

当我循环浏览所有文件时,foo我会这样做

for f in foo* ; do echo "result = $f" ; done
Run Code Online (Sandbox Code Playgroud)

问题是当我没有文件开始时foo:

result = foo*
Run Code Online (Sandbox Code Playgroud)

意味着循环执行一次,即使没有文件开始foo.

这怎么可能?如何循环遍历所有文件(如果没有文件则不循环)?

fed*_*qui 7

您可以通过设置nullglob来停止此行为:

shopt -s nullglob
Run Code Online (Sandbox Code Playgroud)

从链接页面:

nullglob 是一个Bash shell选项,它修改[[glob]]扩展,使得不匹配任何文件的模式扩展为零参数,而不是自身.

您可以使用-u(取消设置,而s不是设置)删除此设置:

shopt -u nullglob
Run Code Online (Sandbox Code Playgroud)

测试

$ touch foo1 foo2 foo3
$ for file in foo*; do echo "$file"; done
foo1
foo2
foo3
$ rm foo*
Run Code Online (Sandbox Code Playgroud)

让我们来看看:

$ for file in foo*; do echo "$file"; done
foo*
Run Code Online (Sandbox Code Playgroud)

设定nullglob:

$ shopt -s nullglob
$ for file in foo*; do echo "$file"; done
$
Run Code Online (Sandbox Code Playgroud)

然后我们禁用该行为:

$ shopt -u nullglob
$ for file in foo*; do echo "$file"; done
foo*
Run Code Online (Sandbox Code Playgroud)


che*_*ner 5

执行此操作的标准方法(如果您不能或不想使用nullglob)是简单地检查文件是否存在。

for file in foo*; do
    [ -f "$file" ] || continue
    ...
done
Run Code Online (Sandbox Code Playgroud)

检查的每个值的开销$file是必要的,因为如果$file膨胀到foo*,你还不知道是否有确实一个文件名为foo*(因为它的模式匹配),或者如果模式未能匹配,并扩大到自身。使用nullglob,当然,因为失败的扩张产生任何参数和循环本身从不执行去除体内这种模糊。