我给Perl的glob
函数提供了一个globs列表和一个字符串。球体按预期处理,但始终找到弦。例如:
$ ls
foo
$ perl -le '@files=glob("*bar"); print @files' ## prints nothing, as expected
$ perl -le '@files=glob("bar"); print @files'
bar
如上所示,即使没有这样的文件,第二个示例也会打印bar
。
我的第一个想法是它的行为就像shell一样,当没有可用的扩展时,一个glob(或被视为glob的东西)扩展到它自己。例如,在csh
中(实际上很糟糕,这就是Perl的glob()
函数似乎遵循的内容,请参阅下面的引用):
% foreach n (*bar*)
foreach: No match.
% foreach n (bar)
foreach? echo $n
foreach? end
bar ## prints the string
但是,根据the docs,glob
应该返回文件名扩展(强调我的):
在列表上下文中,返回EXEX值的文件名扩展列表(可能为空),例如标准的Unix shell / bin / csh。
那么为什么在传递给glob
的参数中没有通配符时它会自动返回?这是一个错误还是我做错了什么?
答案 0 :(得分:11)
使用?
或*
或[]
时,只会返回现有文件或目录。当您的模式只有文字文本或{}
时,将返回所有可能的结果。这与csh完全匹配。
通常,人们会因此而@results = grep -e, glob PATTERN
。
如果您想要对此进行更多控制,也可以使用File::Glob::bsd_glob。 (注意,执行此操作没有额外的开销;因为perl 5.6使用glob()perl时会安静地加载File :: Glob并使用它。)
答案 1 :(得分:8)
我想我希望Perl在后台检查文件是否存在。
Perl 检查文件是否存在:
$ strace perl -e'glob "foo"' 2>&1 | grep foo
execve("/home/mcarey/perl5/perlbrew/perls/5.24.0-debug/bin/perl", ["perl", "-eglob \"foo\""], [/* 39 vars */]) = 0
lstat("foo", {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
那么,当传递给glob的参数中没有通配符时,为什么会返回呢?
因为这就是csh的作用。 Perl的glob
实现基于glob(3)并启用了GLOB_NOMAGIC
标记:
<强> GLOB_NOMAGIC 强>
与GLOB_NOCHECK相同,但如果模式不包含任何特殊字符
*
,?
或[
,则仅附加模式。提供GLOB_NOMAGIC是为了简化历史csh(1)通配行为的实现,并且不应该在其他任何地方使用。<强> GLOB_NOCHECK 强>
如果pattern与任何路径名都不匹配,则glob()返回仅包含pattern ...
的列表
因此,对于像foo
这样没有通配符的模式:
foo
)foo
)由于文件名扩展与模式相同,
glob 'foo'
列表上下文中的将始终返回包含单个元素foo
的列表,无论文件foo
是否存在。