2012-12-26 94 views
12

我有一個perl腳本,通過一個文件夾與幾千個文件。perl -f檢查無法識別文件

當我開始寫劇本我不知道perl的文件::查找功能,所以爲了列出我所用的東西沿着線結構中的所有文件:

open (FILES, "$FIND $FOLDER -type f |"); 
while (my $line = <FILES>) {...} 

但是現在我想我會嘗試從perl這樣做,而不是啓動一個外部程序。 (沒有真正的理由做這種變化,除了想學習使用File :: Find以外)

試圖學習File :: Find查找函數的語義我在命令行上試了一些東西,並比較了輸出爲find。

奇怪的是,有一個程序找到的文件會找到,但perl函數會跳過。

查找工作:

machine:~# find /search/path -type f | grep UNIQ 
/search/path/folder/folder/UNIQ/movie_file_015.MOV 
/search/path/folder/folder/UNIQ/movie_file_145.MOV 
/search/path/folder/folder/UNIQ/Thumbs.db 

machine:~# find /search/path -type f | wc -l 
    6439 

Perl的失敗:

machine:~# perl -e 'use File::Find; find(sub { print $File::Find::name . "\n" if -f }, "/search/path");' | grep UNIQ 
/search/path/folder/folder/UNIQ/movie_file_145.MOV 
/search/path/folder/folder/UNIQ/Thumbs.db 

machine:~# perl -e 'use File::Find; find(sub { print $File::Find::name . "\n" if -f }, "/search/path");' | wc -l 
    6438 

更改爲排除的文件夾,而不是包含文件的工作原理:

machine:~# perl -e 'use File::Find; find(sub { print $File::Find::name . "\n" unless -d }, "/search/path");' | grep UNIQ 
/search/path/folder/folder/UNIQ/movie_file_015.MOV 
/search/path/folder/folder/UNIQ/movie_file_145.MOV 
/search/path/folder/folder/UNIQ/Thumbs.db 
文件之間

唯一的區別是大小:

machine:~# ls -l /search/path/folder/folder/UNIQ/ 
total 4213008 
-rw-rw-r-- 1 user users 4171336632 May 27 2012 movie_file_015.MOV 
-rw-rw-r-- 1 user users 141610616 May 27 2012 movie_file_145.MOV 
-rw-rw-r-- 1 user users  20992 May 27 2012 Thumbs.db 

Perl的有問題的機器是舊的,但不是古代:

machine:~# perl -version 

This is perl, v5.8.8 built for sparc-linux 

Copyright 1987-2006, Larry Wall 

Perl may be copied only under the terms of either the Artistic License or the 
GNU General Public License, which may be found in the Perl 5 source kit. 

Complete documentation for Perl, including FAQ lists, should be found on 
this system using "man perl" or "perldoc perl". If you have access to the 
Internet, point your browser at http://www.perl.org/, the Perl Home Page. 

這是一個已知的bug或東西嗎?

或者我是否達到了'-f'的一些大小限制?該文件幾乎是4GB,並且是最大的選擇。

或者是我的測試(如果-f)選擇不當?

編輯 [試圖STAT文件]:

大文件失敗

machine:~# perl -e 'use Data::Dumper; print Dumper(stat("/search/path/folder/folder/UNIQ/movie_file_015.MOV"));' 

小文件工作

machine:~# perl -e 'use Data::Dumper; print Dumper(stat("/search/path/folder/folder/UNIQ/movie_file_145.MOV"));' 
$VAR1 = 65024; 
$VAR2 = 19989500; 
$VAR3 = 33204; 
$VAR4 = 1; 
$VAR5 = 1004; 
$VAR6 = 100; 
$VAR7 = 0; 
$VAR8 = 141610616; 
$VAR9 = 1349281585; 
$VAR10 = 1338096718; 
$VAR11 = 1352403842; 
$VAR12 = 16384; 
$VAR13 = 276736; 

二進制 '靜' 的作品在這兩個文件

machine:~# stat /search/path/folder/folder/UNIQ/movie_file_015.MOV 
    File: "/search/path/folder/folder/UNIQ/movie_file_015.MOV" 
    Size: 4171336632 Blocks: 8149216 IO Block: 16384 Regular File 
Device: fe00h/65024d  Inode: 19989499 Links: 1 
Access: (0664/-rw-rw-r--) Uid: (1004/user) Gid: ( 100/ users) 
Access: 2012-10-03 18:11:05.000000000 +0200 
Modify: 2012-05-27 07:23:34.000000000 +0200 
Change: 2012-11-08 20:44:02.000000000 +0100 

machine:~# stat /search/path/folder/folder/UNIQ/movie_file_145.MOV 
    File: "/search/path/folder/folder/UNIQ/movie_file_145.MOV" 
    Size: 141610616 Blocks: 276736  IO Block: 16384 Regular File 
Device: fe00h/65024d  Inode: 19989500 Links: 1 
Access: (0664/-rw-rw-r--) Uid: (1004/user) Gid: ( 100/ users) 
Access: 2012-10-03 18:26:25.000000000 +0200 
Modify: 2012-05-27 07:31:58.000000000 +0200 
Change: 2012-11-08 20:44:02.000000000 +0100 

另外:

machine:~# perl -e 'stat("/search/path/folder/folder/UNIQ/movie_file_145.MOV"); print $! . "\n";' 
Bad file descriptor 

machine:~# perl -e 'stat("/search/path/folder/folder/UNIQ/movie_file_015.MOV"); print $! . "\n";' 
Value too large for defined data type 

EDIT2

# perl -V | grep "uselargefiles|FILE_OFFSET_BITS" 
config_args='-Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=sparc-linux -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.8 -Dsitearch=/usr/local/lib/perl/5.8.8 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Dstatic_ext=B ByteLoader GDBM_File POSIX re -Dusemymalloc -Uuselargefiles -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.8 -Dd_dosuid -des' 
useperlio=define d_sfio=undef uselargefiles=undef usesocks=undef 

問題 「解決」:

machine:~# perl -e 'stat("/search/path/folder/folder/UNIQ/movie_file_015.MOV"); print $!{EOVERFLOW} . "\n";' 
92 
machine:~# perl -e 'stat("/search/path/folder/folder/UNIQ/movie_file_145.MOV"); print $!{EOVERFLOW} . "\n";' 
0 

作品:

# perl -e 'use File::Find; find(sub { print $File::Find::name . "\n" if -f or ($!{EOVERFLOW} > 0 and not -d) }, "/search/path");' | grep UNIQ 
/search/path/folder/folder/UNIQ/movie_file_015.MOV 
/search/path/folder/folder/UNIQ/movie_file_145.MOV 
/search/path/folder/folder/UNIQ/Thumbs.db 
+1

好奇。你可以[統計](http://perldoc.perl.org/functions/stat.html)該文件,並告訴我們它返回什麼? –

+0

統計數據似乎也失敗了,我將編輯帖子並添加我的測試結果。 – azzid

+1

失敗?如在,它返回一個空列表? –

回答

10

基地d在a bitGoogling上,看起來您的perl解釋器尚未與large file support編譯,導致stat(以及任何依賴於它的文件測試(包括-f)在內的大於2GB的文件失敗。

要檢查是否屬於這種情況下,運行:

perl -V | grep "uselargefiles|FILE_OFFSET_BITS" 

如果你的Perl有大文件支持,輸出應該顯示類似uselargefiles=define-D_FILE_OFFSET_BITS=64。如果沒有,那很可能你的Perl不支持大文件。

爲什麼需要大文件支持,即使只是stat ing文件也可能有點令人費解。潛在的問題在於,stat(2)系統調用的32位版本,而不是返回一個假的大小,只需將失敗,EOVERFLOW如果施加到大於2GB一個文件:

EOVERFLOW

STAT())路徑是指其大小不能在類型 off_t表示的文件。當應用32位的平臺上的編譯沒有這可能發生210 -D_FILE_OFFSET_BITS = 64調用stat()的文件大小超過(1 < < 31)-1位。「

從技術上來說,接收錯誤應該足以表明命名的文件確實存在(雖然我想這可能是一個真正的堆積如山的目錄也是如此),但Perl是不是足夠聰明,意識到—它只是看到了Stat失敗,所以沒有返回

編輯:作爲池上正確地指出的評論,-f回報undef,而不是0或1,如果STAT(2)調用失敗,並設置$!到錯誤代碼th導致失敗。因此,如果您不介意大小> 2GB的所有目錄條目都是文件,則可以執行類似-f $_ or (not defined -f _ and $!{EOVERFLOW})的操作來檢查它。)

+5

它不會返回任何東西;它返回undef(錯誤)而不是0(不是純文件)並將'$!'設置爲'EOVERLFLOW'。當'-f'返回undef時,您可以通過檢查'$!{EOVERFLOW}'來檢查溢出。 – ikegami

+0

你,先生,非常正確。只要我有可能提供啤酒,您就可以兌現啤酒。 ;) 謝謝! – azzid

+1

@azzid:沒問題。我們可以看到有關啤酒的事情,如果我碰巧有緣在林克平附近的話。 :) –