展望行为这个问题 ,我很惊讶地看到,perl的lstat()
š每一条路径匹配的glob模式:
$ mkdir dir
$ touch dir/{foo,bar,baz}.txt
$ strace -e trace=lstat perl -E 'say $^V; <dir/b*>'
v5.10.1
lstat("dir/baz.txt", {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
lstat("dir/bar.txt", {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
我看到我的Linux系统上相同的行为与glob(pattern)
和<pattern>
,和更高版本的Perl。
我的期望是,文件名匹配将引擎盖下简单地执行opendir / readdir的,而且它不会需要检查的实际路径名这是搜索。
这是什么目的lstat
? 它会影响水珠()的返回?
这种奇怪的行为已经对PerlMonks之前注意到 。 事实证明, glob
电话lstat
支持其GLOB_MARK
标志,它具有这样的效果:
每个路径是一个匹配模式目录中有附加斜线。
要找出一个目录条目是否指的是子目录,你需要stat
的。 这显然是做了,即使没有给出标志。
我想知道同样的事情- “?这是什么LSTAT的目的,这是否会影响水珠()的返回?”
在bsd_glob.c glob2()我注意到内如果需要GLOB_MARK标志分支设置,我还注意到一个呼叫g_stat调用g_lstat之前不是由一个标志检查把守。 两者都达到模式结束时,一个if分支内。 如果我删除这两条线在glob2功能的perl-5.12.4 / EXT /文件的水珠/ bsd_glob.c
- if (g_lstat(pathbuf, &sb, pglob))
- return(0);
唯一perl的测试(使测试),该失败是在内线测试5 /文件的水珠/吨/ basic.t用:
not ok 5
# Failed test at ../ext/File-Glob/t/basic.t line 92.
# Structures begin differing at:
# $got->[0] = 'asdfasdf'
# $expected->[0] = Does not exist
试验5在吨/ basic.t是
# check nonexistent checks
# should return an empty list
# XXX since errfunc is NULL on win32, this test is not valid there
@a = bsd_glob("asdfasdf", 0);
SKIP: {
skip $^O, 1 if $^O eq 'MSWin32' || $^O eq 'NetWare';
is_deeply(\@a, []);
}
如果我更换2线,删除:
+ if (!((pglob->gl_flags & GLOB_NOCHECK) ||
+ ((pglob->gl_flags & GLOB_NOMAGIC) &&
+ !(pglob->gl_flags & GLOB_MAGCHAR)))){
+ if (g_lstat(pathbuf, &sb, pglob))
+ return(0);
+ }
我没有看到“做试验”在Linux x86_64的Perl的5.12.4任何故障(RHEL6.3 2.6.32-358.11.1.el6.x86_64),使用时:
strace -fe trace=lstat perl -e 'use File::Glob q{:glob};
print scalar bsd_glob(q{/var/log/*},GLOB_NOCHECK)'
我再也看不到在DIR每个文件LSTAT电话。 我并不想表明,对于水珠perl的测试(文件的水珠)是全面的(不是),或改变,例如这不会破坏现有的行为(这很可能)。 至于我可以告诉这个(G_L)统计调用的代码在原-BSD / lib中/的libc / GEN / glob.c存在24年前在1990年。
另请参阅:
- 第6章“掌握的Perl”的基准的Perl由Brian d FOY,兰德尔L.施瓦茨包含比较,其中使用glob()并执行opendir()的代码进行比较的代码的部分。
- “未来的水珠(是‘UNIX心态......’)”从迪克·邓恩comp.unix.wizards于1991年。
- Usenet新闻组mod.sources“‘通配’库例程(水珠)”从吉多·范罗苏姆于1986年7月 - 我没有看到这个代码提到了“统计”。