perl -f检查无法识别文件

前端之家收集整理的这篇文章主要介绍了perl -f检查无法识别文件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个perl脚本,通过一个文件夹与几千个文件.

当我开始编写脚本时,我不知道perl File :: Find函数,所以为了列出结构中的所有文件,我使用了以下的一些东西:

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

现在,我想我会尝试从perl这样做,而不是启动一个外部程序.
(没有真正的理由做这个改变,除了想要学习使用File :: Find.)

尝试学习File :: Find find功能的语义我在命令行中尝试了几件事情,并将输出与find进行了比较.

奇怪的是,有1个程序找到的文件,但是perl函数跳过.

查找作品:

  1. machine:~# find /search/path -type f | grep UNIQ
  2. /search/path/folder/folder/UNIQ/movie_file_015.MOV
  3. /search/path/folder/folder/UNIQ/movie_file_145.MOV
  4. /search/path/folder/folder/UNIQ/Thumbs.db
  5.  
  6. machine:~# find /search/path -type f | wc -l
  7. 6439

Perl失败:

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

更改为排除文件夹而不是包含文件的作品:

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

只有文件之间的区别是大小:

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

在机器上的Perl是旧的但不是古老的:

  1. machine:~# perl -version
  2.  
  3. This is perl,v5.8.8 built for sparc-linux
  4.  
  5. Copyright 1987-2006,Larry Wall
  6.  
  7. Perl may be copied only under the terms of either the Artistic License or the
  8. GNU General Public License,which may be found in the Perl 5 source kit.
  9.  
  10. Complete documentation for Perl,including FAQ lists,should be found on
  11. this system using "man perl" or "perldoc perl". If you have access to the
  12. Internet,point your browser at http://www.perl.org/,the Perl Home Page.

这是一个已知的bug还是什么?

或者我碰到一些“-f”的大小限制?该文件几乎是4gb,是最大的选择.

还是我的考试(如果-f)选择不好?

编辑[试图统计档案]:

文件失败

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

文件作品

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

二进制’stat’对两个文件都有效

  1. machine:~# stat /search/path/folder/folder/UNIQ/movie_file_015.MOV
  2. File: "/search/path/folder/folder/UNIQ/movie_file_015.MOV"
  3. Size: 4171336632 Blocks: 8149216 IO Block: 16384 Regular File
  4. Device: fe00h/65024d Inode: 19989499 Links: 1
  5. Access: (0664/-rw-rw-r--) Uid: ( 1004/user) Gid: ( 100/ users)
  6. Access: 2012-10-03 18:11:05.000000000 +0200
  7. Modify: 2012-05-27 07:23:34.000000000 +0200
  8. Change: 2012-11-08 20:44:02.000000000 +0100
  9.  
  10. machine:~# stat /search/path/folder/folder/UNIQ/movie_file_145.MOV
  11. File: "/search/path/folder/folder/UNIQ/movie_file_145.MOV"
  12. Size: 141610616 Blocks: 276736 IO Block: 16384 Regular File
  13. Device: fe00h/65024d Inode: 19989500 Links: 1
  14. Access: (0664/-rw-rw-r--) Uid: ( 1004/user) Gid: ( 100/ users)
  15. Access: 2012-10-03 18:26:25.000000000 +0200
  16. Modify: 2012-05-27 07:31:58.000000000 +0200
  17. Change: 2012-11-08 20:44:02.000000000 +0100

也:

  1. machine:~# perl -e 'stat("/search/path/folder/folder/UNIQ/movie_file_145.MOV"); print $! . "\n";'
  2. Bad file descriptor
  3.  
  4. machine:~# perl -e 'stat("/search/path/folder/folder/UNIQ/movie_file_015.MOV"); print $! . "\n";'
  5. Value too large for defined data type

EDIT2:

  1. # perl -V | grep "uselargefiles|FILE_OFFSET_BITS"
  2. 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'
  3. useperlio=define d_sfio=undef uselargefiles=undef usesocks=undef

问题解决了”:

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

作品:

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

解决方法

基于 Googling a bit,看起来您的perl解释器尚未编译为 large file support,导致stat(以及内部依赖内部的文件测试(包括-f))大于2GB的文件失败.

要检查是否是这种情况,请运行:

  1. perl -V | grep "uselargefiles|FILE_OFFSET_BITS"

如果您的perl具有大量文件支持,则输出显示为uselargefiles = define和-D_FILE_OFFSET_BITS = 64.如果没有,那么你的perl很可能不支持文件.

这可能有点令人困惑,为什么需要大的文件支持,即使只是说明文件.基本的问题是,stat(2)系统调用的32位版本,而不是返回虚假大小,只有在应用于大于2GB的文件时,才会使用EOVERFLOW进行失败:

EOVERFLOW

(stat()) path refers to a file whose size cannot be represented in the type off_t. This can occur when an application compiled on a 32-bit platform without -D_FILE_OFFSET_BITS=64 calls stat() on a file whose size exceeds (1<<31)-1 bits.”

在技​​术上,接收到这个错误应该足以表明命名文件确实存在(尽管我猜想它也可能是一个非常好的目录),但是perl不够聪明,不能意识到 – 它只是看到stat失败了,所以没有回报.

(编辑:由于ikegami在注释中正确注释,如果stat(2)调用失败,-f返回undef而不是0或1,并将$!设置为导致失败的错误代码,所以如果你不介意假设所有大小为> 2GB的目录条目都是文件,您可以执行一些类似于-f $_或(-f _和$!{EOVERFLOW})来检查它.

猜你在找的Perl相关文章