2014-10-07 54 views
-6

我得到這些錯誤爲什麼我會在此Perl程序中收到有關未初始化值的警告?

Use of uninitialized value $vm_name in pattern match (m//) at testscript.pl line 164, <STDIN> line 1.

Use of uninitialized value $vm_name in concatenation (.) or string at testscript.pl line 173, <STDIN> line 1.

誰能幫助?我有一種感覺,這是與子程序,但不能完全弄清楚。我是Perl的新手,幾個小時一直在仔細研究這個問題。

# !/usr/bin/perl 

use strict; 
use warnings; 
use feature ":5.10"; 

############################################################################### 
# Static Variables 
my $templateID = "XXXXXXXXXX"; 
my $serviceID = "XXXXXXXXXXX"; 
############################################################################### 

############################################################################### 
# Global Variables 
my $zone; 
my $input; 
my $zone_ID; 
my $vm_name; 
my $net_default; 
my $net_secondary; 
my $vm_ID; 
my $start; 
my $char_count; 
my $ipaddr_1; 
my $ipaddr_2; 
############################################################################### 

# ----------------------- BASIC CONFIGURATIONS [ZONES] ------------------------ 

print " *** "; 
print " 
ZONES: paris, milan, berlin, geneva, amsterdam, london, slough"; 
print " which zone would you like to deploy to? \n "; 

# Capture input for ZONE 
$input = <STDIN>; 

# Data formatting 
$input =~ s/^\s+|\s+$|^\t//g; 
$zone = lc $input; 

# Declare ZONE to USER 
print "You are deploying to $zone \n"; 

# Map input to function 

# ZONE PARIS 
if ($zone eq "paris") { 
    print "Deploying to $zone\n"; 
    # assign zone id 
    $zone_ID = "374b937d-2051-4440-b02c-a314dd9cb27e"; 
} 

# ZONE MILAN 
elsif ($zone eq "milan") { 
    print "Deploying to $zone\n"; 
    # assign zone id 
    $zone_ID = "58848a37-db49-4518-946a-88911db0ee2b"; 
} 

# ZONE BERLIN 
elsif ($zone eq "berlin") { 
    print "Deploying to $zone\n"; 
    # assign zone id 
    $zone_ID = "fc129b38-d490-4cd9-acf8-838cf7eb168d"; 
} 

# ZONE GENEVE 
elsif ($zone eq "geneva") { 
    print "Deploying to $zone\n"; 
    # assign zone id 
    $zone_ID = "1ef96ec0-9e51-4502-9a81-045bc37ecc0a"; 
} 

# ZONE AMSTERDAM 
elsif ($zone eq "amsterdam") { 
    print "Deploying to $zone\n"; 
    # assign zone id 
    $zone_ID = "3c43b32b-fadf-4629-b8e9-61fb7a5b9bb8"; 
} 

# ZONE SLOUGH 
elsif ($zone eq "slough") { 
    print "Deploying to $zone\n"; 
    # assign zone id 
    $zone_ID = "5343ddc2-919f-4d1b-a8e6-59f91d901f8e"; 
} 

# ZONE LONDON 
elsif ($zone eq "london") { 
    print "Deploying to $zone\n"; 
    # assign zone id 
    $zone_ID = "f6b0d029-8e53-413b-99f3-e0a2a543ee1d"; 
} 

# ELSE 
else { 
    print "Please choose a ZONE"; 
    system('./deploy_vm'); 
} 

# SUBROUTINE: Assigning Virtual Machine name 
sub vm_name { 

    # Name of Virtual Machine 
    print "Enter name of Virtual Machine: \n"; 
    print "[VDC Bug: Please do not include '_' in the name]\n"; 
    my $vm_name = <STDIN>; 

    # Data formatting 
    $vm_name =~ s/^\s+|\s+$//g; 
    print("VM Name: $vm_name"); 

} 

# Apply input filters (no underscores, length constraints) 
if (my $vm_name =~ /_/) { 
    return ('underscore error'); 
    print "Cannot use underscore in VM name, please try again"; 
    vm_name(); 
} 

# DisPlay config 
print " 
$vm_name will be provisioned with: 
1GB HDD and compute offering of 2CPUs with 2GB-RAM"; 

# ----------------------- NETWORK CONFIGURATIONS ------------------------------ 

# Gather network information 
print "available networks in $zone"; 
system('cloudmonkey list networks zoneid=$zone_id filter=name,id'); 

# Users to choose Networks through display 
print ""; 

# Default NIC & IP address 
print "please enter Network ID for Default NIC:\n"; 
$net_default = <STDIN>; 

# IP Address DEFAULT 
print "please enter IP address\n"; 
$ipaddr_1 = <STDIN>; 

# formatting IP address 
$ipaddr_1 =~ m/^\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/; 

# SECONDARY NIC & IP address 
print "please enter Network ID for secondary NIC"; 
$net_secondary = <STDIN>; 

# IP Address SECONDARY 
print "please enter IP address\n"; 
$ipaddr_2 = <STDIN>; 

# Formatting IP address 
$ipaddr_2 =~ m/^\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/; 

print "IP ADDRESS is $ipaddr_2\n"; 

# Deployment notice 
print "... deploying ... \n"; 

# Provision Machine 

# + startvm=false due to provisioning constraints 

system('cloudmonkey deploy virtualmachine startvm=false name=$vm_name diplayname=$vm_name zoneid=$zone_id templateid=$templateID serviceofferingid=$serviceID networkids=$net_default ipaddress=$ipaddr_1'); 

# Add second network to VM 
print "Adding second network to VM"; 
system('cloudmonkey addNicToVirtualMachine networkid=$network_id_second ipaddress=$ip_address_second virtualmachineid=$vm_id'); 

# Display machine ID 
print "$vm_ID"; 
my $feedback = system('cloudmonkey list networks zoneid=$zone_id filter=name,id'); 

# ## ## ## ## ## ## ## ## ## ## ## ## ## ## # 
# #  Sotiris Comments  # # 
# ## ## ## ## ## ## ## ## ## ## ## ## ## ## # 
# if (lc($feedback) =~ /error/) { 
# Warn user and fall back to known state. } 

# User to copy&paste ID 
print "Paste VM ID:\n"; 
$vm_ID = <STDIN>; 

# Data Validation 
$vm_ID  =~ s/^\s+|\s+$//g; 
$vm_ID  = lc $vm_ID; 
$char_count = length($vm_ID); 

# IF statement to impliment length validation 
if ($char_count != 36) { 
    print "your ID is too long/short"; 
} 

# Start Virtual Machine? 
print "Start Virtual Machine $vm_name?"; 
$start = <STDIN>; 

if ($start eq "yes") { 
    system(''); 
} 
elsif ($start eq "no") { 
    system(''); 
} 

# done! 
+0

您必須告訴我們哪一行是164和173. – TLP 2014-10-07 13:53:53

+1

您的錯誤消息不與您的代碼對齊。 – 2014-10-07 13:55:09

+0

我的歉意 第164行是直接在#Apply輸入過濾器(沒有下劃線,長度限制)標題下面開始的代碼,而第173行代碼是在#Dislay配置標題之後直接在 – 3c75 2014-10-07 14:11:53

回答

1
if (my $vm_name =~ /_/) 

總會提醒Use of uninitialized value $vm_name in pattern match下的警告,因爲你錯誤地宣佈另一個詞彙與myif條件。你

也應該過濾用戶輸入作爲

my $vm_name = <STDIN>; 

返回undefined如果用戶按下Ctrl-D或有管道輸入的結束。

+0

嗨Mpapec,有沒有另一種方式,我可以在輸入中查找_,並讓用戶知道他們不能使用這個字符命名他們的虛擬設備(沒有警告?) – 3c75 2014-10-07 14:23:13

+2

@ 3c75,只是刪除這兩個小字母'我''。 – tobyink 2014-10-07 14:24:13

+0

你應該改變你的兩個要點的順序:這是導致錯誤的'我的',所以它應該是第一位的。 – TLP 2014-10-07 14:36:35

0

你到達了輸入的結尾,但你假裝你實際讀的東西,也許你想添加

die "Premature EOF\n" if !defined($vm_name); 

my $vm_name=<STDIN>; 
4

您已經發布了一個貧窮的一塊Perl代碼,你大概已經寫在一個塊中。編程不像那樣工作,特別是在類似腳本的語言中,並且在測試之前,您應該一次只編寫兩行或三行代碼,以便按預期工作。這樣,如果你有任何問題,它可能只是幾行代碼的輸入你知道,但其行爲,你不能解釋。在這種情況下,您的問題中最少的是您的Use of uninitialized value錯誤。

  • 真的不應delcare在你的程序,C語言風格的頂部的一切。聲明應該儘可能接近他們的第一個使用點。

  • 評論應保持絕對最低。一個程序包含的構造是非常罕見的,如果沒有添加註釋,程序就會變得無法理解,並且您的程序會因不必要的註釋而大約100%膨脹

  • 區域和區域ID之間的映射最好作爲Perl哈希,而不是作爲一個if/elsif/else

  • vm_name子程序不會被調用除了在測試if (my $vm_name =~ /_/) { ... },在這裏你的my使用聲明一個新$vm_name始終undef

  • 您對formatting IP address註釋的行根本沒有格式。他們測試了變量的內容是否匹配正則表達式,然後忽略和丟棄測試

  • system使用引號的調用的結果,因此字符串被逐字傳遞給cloudmonkey程序,沒有插值完成。例如,變量名$vm_name$zone_id$templateID$serviceID等都是替換他們的價值觀

有幾個問題比較多,但我強烈建議,正如我在開始時說過,你應該以非常小的部分遞增編寫程序。通過這種方式,您可以看到自己的代碼在行動和嘲笑,同時也確切地知道,在您編寫代碼時,您有堅實的基礎可以繼續發展。

+0

謝謝!我一次只寫了一小段,但是當我嘗試編譯成一個模塊時,事情開始分崩離析:( - 但是感謝您的建議,除了負面投票之外我可以學到 – 3c75 2014-10-07 14:53:02

+1

然後,您還沒有編寫和測試過你的代碼必須徹底,並且在足夠小的部分中,當然,我已經強調過的部分已經*未經過測試,請執行以下操作:看到代碼可以工作,這將是令人鼓舞的,不需要使用Perl模塊因爲你會因爲多用途問題而感到困擾,所以僅僅聲明一堆文件全局變量是適得其反的。你可能更喜歡Stack Exchange的[Code Review site](http://codereview.stackexchange)。因爲它們往往不太重要,Stack Overflow是編程專業人員的網站。 – Borodin 2014-10-07 15:00:45

相關問題