gpt4 book ai didi

perl -f check 无法识别文件

转载 作者:行者123 更新时间:2023-12-03 20:39:16 25 4
gpt4 key购买 nike

我有一个 perl 脚本,它遍历一个包含几千个文件的文件夹。

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

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

但是现在我想我会尝试从 perl 执行此操作,而不是启动外部程序。
(除了想要学习使用 File::Find 之外,没有真正的理由进行此更改。)

为了学习 File::Find find 函数的语义,我在命令行上尝试了一些东西,并将输出与 find 的输出进行了比较。

奇怪的是,程序找到了 1 个文件,但 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.

这是一个已知的错误还是什么?

还是我达到了“-f”的一些大小限制?该文件几乎为 4GB,并且是所选文件中最大的。

还是我的测试(如果 -f)选择不当?

编辑 [尝试统计文件]:

大文件失败
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;

二进制“stat”适用于两个文件
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

编辑2 :
# 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

最佳答案

基于 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()) 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 失败了,所以什么都不返回。

(编辑:正如池上在评论中正确指出的那样,如果 stat(2) 调用失败, -f 返回 undef 而不是 0 或 1,并将 $! 设置为导致失败的错误代码。所以,如果你不要介意假设所有大小 > 2GB 的目录条目都是文件,您可以执行类似 -f $_ or (not defined -f _ and $!{EOVERFLOW}) 的操作来检查它。)

关于perl -f check 无法识别文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14040220/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com