9

当我遍历所有从foo我开始的文件时

for f in foo* ; do echo "result = $f" ; done

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

result = foo*

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

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

4

2 回答 2

10

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

shopt -s nullglob

从链接页面:

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

-u您可以使用(未​​设置,而s用于设置)删除此设置:

shopt -u nullglob

测试

$ touch foo1 foo2 foo3
$ for file in foo*; do echo "$file"; done
foo1
foo2
foo3
$ rm foo*

让我们来看看:

$ for file in foo*; do echo "$file"; done
foo*

设置nullglob

$ shopt -s nullglob
$ for file in foo*; do echo "$file"; done
$

然后我们禁用该行为:

$ shopt -u nullglob
$ for file in foo*; do echo "$file"; done
foo*
于 2014-10-08T11:29:30.820 回答
5

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

for file in foo*; do
    [ -f "$file" ] || continue
    ...
done

检查每个值的开销$file是必要的,因为如果$file扩展为foo*,您还不知道是否确实一个名为的文件foo*(因为它与模式匹配),或者模式是否无法匹配并扩展为自身。nullglob当然,使用可以消除这种歧义,因为失败的扩展不会产生任何参数,并且循环本身永远不会执行主体。

于 2014-10-08T14:34:20.123 回答