2013-05-09 56 views
6

展望行爲this question,我驚訝地看到,perl的lstat()小號每個路徑匹配的glob模式:爲什麼glob lstat匹配項?

$ 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 

我看到glob(pattern)<pattern>我的Linux系統上相同的行爲,並與更高版本的perl的。

我的期望是,通配將引擎蓋下簡單地執行opendir/readdir的,而且它不會需要檢查的實際路徑名這是搜索。

這是什麼lstat的用途?它會影響glob()的返回嗎?

+0

@mpapec,我會更新我的期望,當我在下一個終端,謝謝。 – pilcrow 2013-05-09 12:32:41

+0

只是一個不行:我不得不在我的系統上將'lstat'更改爲'lstat64'。 – choroba 2013-05-09 12:40:36

回答

8

這種奇怪的行爲已被noticed before on PerlMonks。事實證明,glob電話lstat,以支持其GLOB_MARK標誌,它具有這樣的效果:

每個路徑是一個匹配模式目錄中有附加斜線。

要知道目錄條目是否指的是子目錄,你需要stat它。即使沒有給出國旗,這顯然是完成的。

+0

這似乎是完全它,謝謝。 – pilcrow 2013-05-09 13:40:54

2

我想知道同樣的事情 - 「?這是什麼LSTAT的目的,這是否會影響水珠()的返回?」

在bsd_glob.c glob2()我注意到內如果需要GLOB_MARK標誌分支設置,我還注意到一個呼叫g_stat調用g_lstat之前不是由一個標誌檢查把守。當達到模式結束時,兩者都在if分支內。 如果刪除這些2條線路中的glob2功能在Perl-5.12.4/EXT /文件-水珠/ bsd_glob.c

- if (g_lstat(pathbuf, &sb, pglob)) 
-  return(0); 

唯一perl的測試(使測試),該失敗是試驗5在EXT /文件水珠/噸/ 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調用。 我的意思並不是說glob(File-Glob)的perl測試是全面的(他們不是),或者像這樣的改變不會破壞現有的 行爲(這似乎很可能)。至於我可以告訴這個(G_L)統計調用的代碼在原-BSD存在/ lib中/的libc/GEN/glob.c 24年前,1990年

另見:

  • 章6。「掌握Perl」的Perl標準作者:brian d foy,Randal L. Schwartz 包含了比較使用glob()和opendir()的代碼進行比較的代碼段。
  • 從迪克·鄧恩comp.unix.wizards「未來的水珠(是‘UNIX心態......’)」於1991年
  • Usenet新聞組mod.sources「‘通配’庫例程(水珠)」從圭多面包車Rossum在1986年7月 - 我在這段代碼中沒有看到對「stat」的引用。