2014-10-07 4 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을 처음 사용하고 있으며 몇 시간 동안이 문제를 해결하고있다. 실수 if 조건 내에서 my와 다른 어휘를 선언하고 같은

# !/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

+1

오류 메시지가 코드와 일치하지 않습니다. –

+0

사과, 라인 164는 # 입력 필터 바로 밑에서 시작하는 코드입니다 (밑줄, 길이 제약 없음) 제목과 라인 173은 #Dislay 구성 머리글 바로 아래의 코드입니다. – 3c75

답변

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

항상 경고에서 Use of uninitialized value $vm_name in pattern match을 경고합니다. 사용자가 누를 경우 Ctrl-D

my $vm_name = <STDIN>; 

미정 반품 입력 파이프의 단부가 있다는

또한 사용자 입력을 살균한다.

+0

안녕하세요, Mpapec, 거기에 또 다른 방법은 아마 _ 내가 입력에서 찾을 수 있으며 사용자가 가상 ​​장치 (경고없이?) – 3c75

+2

@@c75, 그냥 두 문자를 제거 할 때이 문자를 사용할 수 없다는 것을 알려주 수 있습니까? 작은 글자'my'. – tobyink

+0

두 가지 주요 점의 순서를 변경해야합니다. 오류를 일으키는 것은 'my'이므로 첫 번째 오류가 발생해야합니다. – TLP

0

당신은 입력의 끝에 도달하고, 그러나 당신은 당신이 실제로 뭔가를 읽어 척. 당신의 빈약 한 조각을 게시 한

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

my $vm_name=<STDIN>; 
4

후 어쩌면 당신은 추가 할 당신이 아마도 하나의 덩어리로 작성한 Perl 코드. 프로그래밍은 특히 스크립트와 같은 언어에서 그와 같이 작동하지 않으며 예상 한대로 작동하는지 테스트하기 전에 한 번에 2 ~ 3 줄만 작성해야합니다. 그렇게하면 질문이있는 경우 입력 내용을 알고있는 코드 몇 줄에 불과하지만 설명 할 수없는 행동이있을 수 있습니다. 이 경우 귀하의 Use of uninitialized value 오류가 귀하의 걱정거리 중 가장 적은 것입니다.

  • 당신 정말은 프로그램, C 스타일의 상단에있는 모든 delcare 안된다. 선언은 가능한 한 첫 번째 사용 지점에 가깝습니다.

  • 설명은 절대 으로 유지되어야합니다. 프로그램에 주석을 추가하지 않아도 이해할 수없는 구조가 포함되어 있고 프로그램이 불필요한 주석으로 약 100 % 부풀려지는 경우는 거의 없습니다.

  • 영역과 영역 ID 간의 매핑은 Perl 해시로 구현하는 것이 가장 좋으며, 하지 항상 될 것 vm_name 서브 루틴이 테스트 if (my $vm_name =~ /_/) { ... }를 제외하고 호출되지 및 my의 사용 여기에 새로운 $vm_name을 선언 않습니다

  • if/elsif/else 체인 등 undef

  • formatting IP address으로 주석 처리 한 행은 전혀 서식을 지정하지 않습니다.그들은 변수 '내용이 정규 표현식과 일치하는지 여부를 테스트하고, 문자열이 cloudmonkey 프로그램에 그대로 전달됩니다 누른 후 무시하고 시험

  • system 사용 단일 따옴표로 호출의 결과를 폐기하고, 보간이 수행되지 않습니다. 등 $serviceID하지 자신의 값으로 대체됩니다 예를 들어, 변수 이름 $vm_name, $zone_id, $templateID,

가 몇 가지 더 많은 문제가 있지만, 내가 처음에 말했듯이 난 강력하게, 당신을 제안 아주 작은 부분에 점진적으로 프로그램을 작성해야합니다. 그런 식으로 코드를 실행하고 wortking하는 것을 보는 즐거운 기쁨을 누릴 수있을뿐 아니라 작성하는대로 확고한 기반을 구축 할 수 있습니다.

+0

고마워요! 나는 한 번에이 작은 글을 썼지 만 하나의 모듈로 컴파일하려고했을 때 물건이 떨어지기 시작했다. (그러나 - 네 조언에 대해 감사한다. 제외 표 이외의 것을 배운다. – 3c75

+1

다음 글을 쓰지 않았고 테스트하지 않았다. 코드를 철저히, 그리고 작은 부분으로 작성하십시오. 필자가 강조한 부분은 테스트되지 않았습니다. 수행하십시오 : 코드 작업을 보도록 권장합니다! Perl 모듈을 다음과 같이 사용할 필요가 없습니다. 스택 익스체인지의 [Code Review site] (http : //codereview.stackexchange.)를 선호 할 수도있다.이 코드를 사용하면 다중 - 사용 문제로 어려움을 겪게 될 것이므로 파일 - 글로벌 변수를 선언하는 것은 역효과가있다.com /) 프로그래밍 전문가를위한 사이트 인 Stack Overflow가 그다지 중요하지 않은 경향이 있습니다. – Borodin