2013-12-16 143 views
0

我有一個將df解析爲perl可以使用的東西的腳本。在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. 

更新: 我昨晚看了DF模塊CPAN在家裏,但我必須讓系統管理員批准,把它安裝。 在DF文件系統太長,所以它被打印到另一行。這弄亂了數據轉儲打印輸出 - 一些散列值被標記爲undef。

[email protected]]:~/.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 
[[email protected]]:~/.wjohnson> 
[[email protected]]:~/.wjohnson> 
[[email protected]]:~/.wjohnson> 
[[email protected]]:~/.wjohnson> 
[[email protected]]:~/.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 
[[email protected]]:~/.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解決 - 但必須有更好的方法。

+1

輕微挑剔,但代碼中和錯誤中的行號都是1。 – ThisSuitIsBlackNot

+3

您是否嘗試過使用Data :: Dumper在運行時檢查%info中的內容?我懷疑用df,你會發現設備名稱可能會變長,並且強制剩下的數據放在下一行,因此會對哈希中未初始化的數據提出警告。 編輯:看着df的幫助,我想你可能想要通過-P選項。 – razzmataz

+1

當我在我的機器上運行這個命令時,我沒有收到任何錯誤,但是接下來'df'在我們的每臺機器上都返回不同的東西。 –

回答

5

perldiag

,如同其在已經定義中使用了未定義的值。它被解釋爲「」或0,但也許這是一個錯誤。要抑制此警告,請爲您的變量分配一個定義的值。

爲了幫助你弄清楚什麼是未定義的,perl會試着告訴你未定義的變量名(如果有的話)。在某些情況下,它不能執行此操作,因此它還會告訴您在未使用的值中使用了哪些操作。但是,請注意,perl會優化您的程序,以防止警告中顯示的操作可能不會真正出現在程序中。例如,「那$ foo」通常被優化爲「那個」。 $ foo,並且警告將引用並置(。)運算符,即使沒有。在你的程序中。

總之,你使用的變量,如果它包含一個字符串或數字,但其價值是undef,也許是因爲它從未收到一個值,或因爲它不存在。

也許你正在使用錯誤的變量名稱。也許你需要提供一個默認值。原因無數,所以沒有單一的修復。

+1

這應該是在某種類型的常見問題解答上(很像[什麼是安裝缺少的Perl模塊的最簡單方法?](http://stackoverflow.com/questions/65865/whats-the-easiest-way-to-install-a-missing-perl-module) ) – ThisSuitIsBlackNot

1

讓我們專注於第一個警告。在20/21行左右的某處,您會收到undef警告。正如已經指出的那樣,要麼你指定了一個不存在的變量(mispelling?),要麼變量從未初始化。

只要您測試它是否未初始化,留下變量單元化沒有任何問題。

我用了很多的哈希結構,並實例他們:

my %test_data;

如果我的邏輯莫名其妙地圍繞填補這一哈希支,然後當我去使用%test_data,我第一次測試,看是否它設置爲undef

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

在你的情況,你設置$percentage的值,但它似乎$percentage設置爲undef$percentage =~ s{%}{};

所以,在你到達那條線之前,你需要繞着它轉移,如果!$percentage

1

你的代碼似乎對我很好(在Ubuntu 13.10上運行Perl 5.14.2)。

我懷疑問題是您的機器上的df命令沒有以與代碼期望的相同格式返回數據。