我看到了很多来自*.cmd文件的grepped行。所以似乎
排除选项对我不起作用。
有一个称为
nullglob
的shell选项,它控制着当没有匹配的文件时,shell模式的扩展。
所以,考虑以下环境:
sh$ touch f.cmd g.sh
sh$ mkdir sub
sh$ echo ckim > sub/h.cmd
sh$ echo ckim > sub/i.cmd
在我的系统上(未设置
nullglob
),以下命令:
grep --exclude=*.cmd ckim * -r
被 shell 解释为扩展("understood"):
grep --exclude=*.cmd ckim f.cmd g.sh sub -r
也就是说,我将递归地(
-r
)搜索以
f.cmd
、
g.sh
和
sub
开头的字符串
skim
,但排除与模式“*.cmd”匹配的任何文件。
结果是:
# nullglob is unset
sh$ grep --exclude=*.cmd ckim * -r
sub/i.sh:ckim
但是,如果您的环境中设置了nullglob
选项,则相同的命令会扩展为:
grep ckim f.cmd g.sh sub -r
请注意,整个
--exclude=...
已经消失了。 因此结果是:
# nullglob is set
sh$ grep --exclude=*.cmd ckim * -r
sub/i.sh:ckim
sub/h.cmd:ckim
现在,来解释一下。当shell遇到一个glob模式(即包含*或?或其他特殊字符的模式)时,它会将其与匹配的文件扩展。但是,如果没有匹配的文件,它会让模式保持不变(如果未设置nullglob),或者用“nothing”替换它(如果设置了nullglob)。
这里的模式是--include=*.cmd(整个字符串因为其中没有空格)。如果您出奇迹般地有一个匹配此模式的文件,它将被替换。否则,它要么保持原样,要么完全删除 - 这取决于nullglob。
您可以轻松地显示、设置(
-s
)或取消设置(
-u
)当前bash的
nullglob
选项的状态:
sh$ shopt nullglob
nullglob on
sh$ shopt -u nullglob
sh$ shopt nullglob
nullglob off
sh$ shopt -s nullglob
sh$ shopt nullglob
nullglob on
pattern
参数。 - Avinash Raj