【问题标题】:Use of uninitialized value in Perl hash在 Perl 哈希中使用未初始化的值
【发布时间】:2013-12-16 18:42:14
【问题描述】:

我有一个脚本可以将 df 解析成 perl 可以使用的东西。

 1 #!/usr/bin/perl
 2 use strict;
 3 use warnings;
 4
 5 my @headers = qw(name size used free capacity mount);
 6 my @df = `df -k`;
 7 shift @df;  # get rid of the header
 8
 9 my %devices;
10 for my $line (@df) {
11     my %info;
12     @info{@headers} = split /\s+/, $line;  # note the hash slice
13     $info{capacity} = _percentage_to_decimal($info{capacity});
14     $devices{ $info{mount} } = \%info;
15 }
16
17 # Change 12.3% to .123
18 sub _percentage_to_decimal {
19     my $percentage = shift;
20     $percentage =~ s{%}{};
21     return $percentage / 100;
22 }
23 # Now the information for each device is in a hash of hashes.
24
25 # Show how much space is free in device /dev/ad4s1e
26 print $devices{"/production/log"}{free} ;
27 print "\n";
28 for my $info (values %devices) {
29     # Skip to the next device if its capacity is not over 60%.
30     next unless $info->{capacity} > .10;
31
32     # Print some info about each device
33     printf "%s is at %d%% with %dK remaining.\n",
34         $info->{mount}, $info->{capacity}*100, $info->{free};
35 }

但是,我不断收到这些警告。

Use of uninitialized value in substitution (s///) at ./get_df line 21.
Use of uninitialized value in division (/) at ./get_df line 22.
Use of uninitialized value in hash element at ./get_df line 15.
Use of uninitialized value in substitution (s///) at ./get_df line 21.
Use of uninitialized value in division (/) at ./get_df line 22.
Use of uninitialized value in hash element at ./get_df line 15.
Use of uninitialized value in substitution (s///) at ./get_df line 21.
Use of uninitialized value in division (/) at ./get_df line 22.
Use of uninitialized value in hash element at ./get_df line 15.
Use of uninitialized value in substitution (s///) at ./get_df line 21.
Use of uninitialized value in division (/) at ./get_df line 22.
Use of uninitialized value in hash element at ./get_df line 15.
Use of uninitialized value in substitution (s///) at ./get_df line 21.
Use of uninitialized value in division (/) at ./get_df line 22.
Use of uninitialized value in hash element at ./get_df line 15.
9006792
/production/log is at 70% with 9006792K remaining.
/ is at 37% with 17037532K remaining.
/production is at 11% with 13171728K remaining.
/export/home is at 24% with 11199904K remaining.
/production/archive is at 18% with 8095796K remaining.
/boot is at 28% with 68351K remaining.

更新: 昨晚我在家里查看了 CPAN 上的 DF 模块,但我必须获得系统管理员的批准才能安装它。 在 df 文件系统太长,所以它被打印到另一行。这弄乱了数据转储器的打印输出——一些哈希值被标记为 undef。

casper@casperbox]:~/.wjohnson> df -k
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
                      28313732   9816924  17035356  37% /
/dev/sda1               101086     27516     68351  29% /boot
tmpfs                  2987896         0   2987896   0% /dev/shm
/dev/mapper/VolGroupPROD-ExportHome
                      15481840   3495504  11199904  24% /export/home
/dev/mapper/VolGroupPROD-Production
                      15481840   1523692  13171716  11% /production
/dev/mapper/VolGroupPROD-ProdLog
                      30963708  20410952   8979892  70% /production/log
/dev/mapper/VolGroupPROD-ProdArchive
                      10313016   1693640   8095500  18% /production/archive
[casper@casperbox]:~/.wjohnson>
[casper@casperbox]:~/.wjohnson>
[casper@casperbox]:~/.wjohnson>
[casper@casperbox]:~/.wjohnson>
[casper@casperbox]:~/.wjohnson> df -k | grep -v dev
Filesystem           1K-blocks      Used Available Use% Mounted on
                      28313732   9816924  17035356  37% /
                      15481840   3495504  11199904  24% /export/home
                      15481840   1523692  13171716  11% /production
                      30963708  20410952   8979892  70% /production/log
                      10313016   1693640   8095500  18% /production/archive
[casper@casperbox]:~/.wjohnson>

来自 Data::Dumper - 许多哈希值都未定义。有没有办法可以预定义哈希值。我想学会摆脱它们。

$VAR1 = {};
Use of uninitialized value in substitution (s///) at ./get_df.just_capacity line 24.
Use of uninitialized value in division (/) at ./get_df.just_capacity line 25.
Use of uninitialized value in hash element at ./get_df.just_capacity line 17.
$VAR1 = {
          '' => {
                  'free' => undef,
                  'mount' => undef,
                  'used' => undef,
                  'name' => '/dev/mapper/VolGroup00-LogVol00',
                  'capacity' => '0',
                  'size' => undef
            }
        };
$VAR1 = {};
$VAR1 = {
          '' => {
                  'free' => undef,
                  'mount' => undef,
                  'used' => undef,
                  'name' => '/dev/mapper/VolGroup00-LogVol00',
                  'capacity' => '0',
                  'size' => undef
                },

这可以通过使用df -k | grep -v var 解决——但必须有更好的方法。

【问题讨论】:

  • 次要的挑剔,但您的代码和错误中的行号减少了一个。
  • 您是否尝试过在运行时使用 Data::Dumper 检查 %info 中的内容?我怀疑使用 df,您会发现设备名称可能会变长,并强制其余数据位于下一行,因此会发出有关哈希中未初始化数据的警告。编辑:查看 df 的帮助,我认为您可能需要传递 -P 选项。
  • 我在我的机器上运行它时没有收到任何错误,但是df 在我们的每台机器上返回不同的东西。
  • 我已确认我收到错误,因为我的设备名称之一相当长。
  • 回复:“我查看了 CPAN 上的 DF 模块……但我必须获得系统管理员的批准才能安装它。” You don't need root access to install modules(如果是这个问题;我知道也可能有公司政策等)

标签: perl hash undefined


【解决方案1】:

perldiag:

使用了一个未定义的值,就好像它已经定义了一样。它被解释为“”或 0,但可能是一个错误。要抑制此警告,请为您的变量分配一个定义的值。

为了帮助您找出未定义的内容,perl 将尝试告诉您未定义的变量的名称(如果有的话)。在某些情况下它无法做到这一点,因此它还会告诉您在哪个操作中使用了未定义的值。但是请注意,perl 优化了您的程序,并且警告中显示的操作不一定会在您的程序中出现。例如,“that $foo”通常被优化为“that”。 $foo ,警告将引用连接 (.) 运算符,即使没有 .在你的程序中。

简而言之,您使用了一个变量,就好像它包含一个字符串或数字一样,但它的值是undef,可能是因为它从未收到过值或者因为它不存在。

也许您使用了错误的变量名。也许您需要提供默认值。原因不胜枚举,所以没有单一的解决方法。

【讨论】:

【解决方案2】:

让我们专注于第一个警告。在第 20/21 行的某个地方,您会收到一个 undef 警告。正如已经指出的那样,要么您指定了一个不存在的变量(拼写错误?),要么该变量从未被初始化。

让变量未初始化并没有什么问题,只要你测试一下它是否未初始化。

我使用了很多哈希结构,并将它们实例化:

my %test_data;

如果我的逻辑以某种方式围绕填充此哈希进行了分支,那么当我使用 %test_data 时,我首先测试它是否设置为 undef

if(%test_data)
{
  <do something using the hash>;
}

在您的情况下,您将$percentage 设置为一个值,但似乎$percentage 设置为undef$percentage =~ s{%}{};

所以,在你到达那条线之前,如果!$percentage,你需要绕过它。

【讨论】:

    【解决方案3】:

    您的代码对我来说似乎运行良好(在 Ubuntu 13.10 上运行 Perl 5.14.2)。

    我怀疑问题在于您机器上的df 命令没有以与代码预期相同的格式返回数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-24
      • 2013-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-23
      • 2023-03-30
      • 1970-01-01
      相关资源
      最近更新 更多