为什么du和Perl的-s为文件大小赋予不同的值?

时间:2010-09-22 19:44:44

标签: perl file unix storage command

根据评论更新:

我有outlog.txt文件,其中包含多个文件名,例如:2345_535_Dell&HP_3PAR_DEAL.txt,类似地有很多文件名但不是文件所在的实际文件夹,所以在代码中我将文件名附加到folderpath以获取实际文件位置。现在,我希望获得outlog.txt中存在的所有文件的磁盘使用量以及outlog.txt中存在的所有文件的总磁盘使用量。

我尝试过两种方法perl -s和我的($ size)= split('',du`“$ folderpath / $ _”`)但这两种方法都给了我不同的值,当我使用时du比得到一些数值但是它没有给我单位,有没有一种方法可以让人类在不使用-h选项的情况下阅读,因为它不适用于我的系统?

背景资料

我的目标是获取文件的大小,目前我使用perl -s来获取文件大小。我也尝试了du并且获得了相同文件大小的不同值。我无法理解这是如何运作的。

问:为什么duperl -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";

礼貌:RickF

更新

问: 如何获取每个文件的磁盘使用值而不是文件大小,这意味着我如何获得每个文件的du值而不是文件的perl -s值?

操作系统信息 uname:SunOS uname -v:Generic_117350-39

更新代码:根据大脑的方法,但仍然将值打印为零,而不是实际值,是否有任何建议?

更新 如果我使用我的($ size)= split('',du "$folderpath/$_");我得到的是du值,但它给了我一些数字,如何在不使用-h选项的情况下将其变为人类可读?

 #!/usr/bin/perl
 use strict;
 use warnings;

my $folderpath = '/Project/upload';
open my $IN, '<', 'outlog.txt';
my $total;
while (<$IN>) {
    chomp;
    #my( $block_size, $blocks ) = ( stat( "$_" ) )[11,12];
    #my $du_size = $block_size * $blocks;
    my ($size) = split(' ', `du "$folderpath/$_"); 
    #my $size = -s "$folderpath/$_";
    print "$_ => $size\n";
    $total += $size;
}
print "Total => $total\n";

4 个答案:

答案 0 :(得分:8)

du报告实际磁盘使用情况,Perl的-s报告文件大小。因此,如果文件长度为四个字节,则其大小为4个字节,但磁盘使用量为4千字节(取决于文件系统的设置方式)。

您还会看到sparse files的大小不同。稀疏文件占用的空间比它们声称的少。

答案 1 :(得分:4)

默认情况下,du显示文件使用的块数(大多数系统中每个块为512字节),而perl的-s显示字节。

至于为什么du的副本没有-h选项,您不会告诉我们您正在使用的操作系统;它似乎包括一个可怕的过时版本的程序。

更新:要获取perl中的磁盘使用情况,您可以使用Filesys::DiskUsage模块。

答案 2 :(得分:3)

du代表“Disk Used”,并报告磁盘上文件的物理大小。如果文件稀疏,则可能比其逻辑大小小得多,这是-s报告的内容。两者都是“准确的”,它们只是衡量不同的东西。

错误消息表明您计算机上安装的du版本无法理解-h选项。

答案 3 :(得分:1)

如果您希望du提供与Perl -s相同的结果,请尝试du -b。如果您的du支持它,则会显示“明显大小”,这与磁盘使用情况不同,正如其他人所说的那样。

但要执行此操作,您必须更新du

更新OP的更新代码:确保该文件存在于当前工作目录中。您可能必须预先添加目录以确保Perl正在查找文件。

如果你不在任何地方使用$_,它也可以澄清一些事情:

while( my $line = <$IN> ) {
  chomp $line;
  my( $block_size, $blocks ) = ( stat( $line ) )[11,12];
  ...
}

通过这种方式,您可以免于对$_的无意更改。