为什么du和Perl';s-s为文件大小提供不同的值?
根据评论更新:为什么du和Perl';s-s为文件大小提供不同的值?,perl,file,unix,storage,command,Perl,File,Unix,Storage,Command,根据评论更新: my $folderpath = 'the_path'; open my $IN, '<', 'path/to/infile'; my $total; while (<$IN>) { chomp; my $size = -s "$folderpath/$_"; print "$_ => $size\n"; $total += $size; } print "Total => $total\n"; 我有一个包含多个文件
my $folderpath = 'the_path';
open my $IN, '<', 'path/to/infile';
my $total;
while (<$IN>) {
chomp;
my $size = -s "$folderpath/$_";
print "$_ => $size\n";
$total += $size;
}
print "Total => $total\n";
我有一个包含多个文件名的outlog.txt
文件,例如:2345\u 535\u Dell&HP\u 3PAR\u DEAL.txt
,同样有许多文件名,但不是文件所在的实际文件夹,因此在代码中,我将文件名附加到folderpath以获得实际的文件位置。现在,我想获取outlog.txt
中所有文件的磁盘使用率,以及outlog.txt
中所有文件的总磁盘使用率
我尝试了两种方法perl-s
和my($size)=split(“”,du`“$folderpath/$\u``),但这两种方法都给了我不同的值,而且当我使用du
时,我会得到一些数值,但它不会给我单位,有没有一种方法可以不使用-h
选项让人可读,因为它不在我的系统上工作
背景信息
我的目标是获得文件的大小,目前我正在使用perl-s
来获得文件大小。我还尝试了du
,对于同一个文件的大小,我得到了不同的值。我不明白这是怎么回事
Q:为什么du
和perl-s
会给出不同的大小值?它们内部如何工作?两个不同的值中哪一个更准确?另外,我不确定为什么du-h filename
会给我一个非法的表达式错误:
bash-2.03$ du -h test.txt
/usr/bin/du: illegal option -- h
usage: du [-a][-d][-k][-r][-o|-s][-L] [file ...]
代码:
my $folderpath = 'the_path';
open my $IN, '<', 'path/to/infile';
my $total;
while (<$IN>) {
chomp;
my $size = -s "$folderpath/$_";
print "$_ => $size\n";
$total += $size;
}
print "Total => $total\n";
du
代表“使用的磁盘”,并报告磁盘上文件的物理大小。如果文件是稀疏的,这可能比其逻辑大小小得多,这是-s
报告的。两者都是“精确的”,它们只是测量不同的东西
错误消息表示您机器上安装的
du
版本不理解-h
选项。du
报告实际磁盘使用情况,Perl的-s
报告文件大小。因此,如果一个文件有四个字节长,那么它的大小将是四个字节,但磁盘使用量是四千字节(取决于文件系统的设置方式)
您还将看到的大小不同。稀疏文件占用的空间比它们声称的要少。默认情况下,
du
显示文件使用的块数(在大多数系统中,每个块为512字节),而perl的-s
显示字节
至于为什么您的du
副本没有-h选项,您没有告诉我们您使用的是什么操作系统;它似乎包含了一个非常过时的程序版本
更新:要获得perl中的磁盘使用率,可以使用该模块。如果希望
du
给出与perl的-s
相同的结果,请尝试du-b
。如果您的du
支持它,则会给出“表观大小”,这与其他人所说的磁盘使用情况不同
但要做到这一点,您必须更新您的du
更新OP的更新代码:确保文件存在于当前工作目录中。您可能必须在目录前加上前缀,以确保Perl正在查找该文件
如果您不在任何地方使用$\uu
,它也可能会澄清一些问题:
while( my $line = <$IN> ) {
chomp $line;
my( $block_size, $blocks ) = ( stat( $line ) )[11,12];
...
}
while(我的$line=){
chomp$行;
我的($block_size,$blocks)=(stat($line))[11,12];
...
}
通过这种方式,您可以避免对
$\ucode>的意外更改。我发现,如果du
显示块(512字节),那么这个数字会更小,因为一个块可以容纳512字节,而不是因为文件稀疏?除非我遗漏了什么。@Evan Carroll,du
能够以不同的单位报告大小。我不确定SunOS的默认单位是什么。试试mandu
@Wooble-我没有为Filesys::DiskUsage安装pm
,cpanp install Filesys::DiskUsage
@Evan:这是命令吗,实际上我还是在早期使用Perl
所以不太熟悉用智能的方式做Perl:0
@Rachel Yep,对于5.10+使用cpanp
,该命令将为您完成所有操作。@Rachel:您还应该cpanp安装autodie
,并使用autodie代码>(您没有在代码中选中$!
)Evan,定义的不是必需的。当我们到达文件末尾时,
返回undef
,它被分配到$line
。因此,赋值的返回值也是unde
,它被转换为false,并且while()
循环退出。这就是为什么我回滚了您添加了定义的检查的编辑。@CanSpice这是必要的,如果您得到一个名为0或“”的文件,您将停止执行(并不是说执行次数太多,而是让结果依赖于perl真值表,而不是eof())@Evan:请查看,然后阅读。@Ether:您是对的,但是Perl文档具有误导性。他们说,“如果且仅当输入符号是while语句的条件内部的唯一内容”——但后来与“且仅当”部分相矛盾,显示while(my$line=)
的行为方式也相同。让我们想知道这部电影到底会在什么情况下上演。@j_random:谢谢;这一点我们可以在perldocs的下一个版本中得到澄清。