我给Perl的glob函数提供了一个globs列表和一个字符串.球体按预期处理,但始终找到弦.例如:
$ ls
foo
$ perl -le '@files=glob("*bar"); print @files' ## prints nothing, as expected
$ perl -le '@files=glob("bar"); print @files'
bar
Run Code Online (Sandbox Code Playgroud)
如上所示,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
Run Code Online (Sandbox Code Playgroud)
但是,根据文档,glob应该返回文件名扩展(强调我的):
在列表上下文中,返回EXPR值的文件名扩展(可能为空)列表,例如标准的Unix shell/bin/csh.
那么为什么在传递给参数的参数中没有通配符时它会返回glob?这是一个错误还是我做错了什么?
yst*_*sth 11
使用?或*或时[],仅返回现有文件或目录.当您的模式只有文字文本或时{},将返回所有可能的结果.这与csh完全匹配.
通常,人们会这样做@results = grep -e, glob PATTERN.
或者,如果您想要更多地控制它,可以使用File :: Glob :: bsd_glob.(注意,执行此操作没有额外的开销;因为perl 5.6在使用glob()perl时会安静地加载File :: Glob并使用它.)
我想我希望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
Run Code Online (Sandbox Code Playgroud)
那么为什么在传递给glob的参数中没有通配符时它会返回?
因为这就是csh所做的.Perl的实现glob基于glob(3)并GLOB_NOMAGIC启用了标志:
GLOB_NOMAGIC
与GLOB_NOCHECK相同,但只有在不包含任何特殊字符时才附加模式
*,?或者[.提供GLOB_NOMAGIC是为了简化历史csh(1)通配行为的实现,并且可能不应该在其他任何地方使用.GLOB_NOCHECK
如果pattern与任何路径名不匹配,则glob()返回仅包含模式的列表...
所以,对于foo没有通配符的模式:
foo则返回文件名expansion()foo则返回pattern()由于文件名扩展与模式相同,
glob 'foo'
Run Code Online (Sandbox Code Playgroud)
在列表上下文中将始终返回包含单个元素的列表foo,无论文件是否foo存在.