2013-06-11 76 views
1

我正在使用Perl CLI框架來編寫一些腳本。現在我想將控制模塊中的變量傳遞給子命令模塊。我試圖將變量設置爲控制模塊中的全局變量,但子命令模塊仍然無法獲取變量。它甚至無法在同一模塊中共享全局變量。執行腳本時會出現一些錯誤消息:如何使用Perl CLI Framework共享兩個模塊之間的全局變量?

[root @ old]#perl pc --ip = dsfa --device dsfasdf on 使用未初始化的值$ Power :: Control :: data in concatenation(。)或字符串在電源/ Control.pm線63

的globla數據是 使用未初始化值$電源的::控制::數據在級聯(。)或字符串在電源/ Control.pm線75

來自父代的數據是

設備名稱是dsfasdf

的IP地址是DSFA

這是

這裏的命令腳本PC:

#! /usr/bin/perl 

use strict; 
use warnings; 
use Power::Control; 

use lib 'lib'; 

# ---- EXECUTION ---- 
Power::Control->run(); # Launch command 

下面是電源/ Control.pm:

package Power::Control; 
use base qw(CLI::Framework); 

use strict; 
use warnings; 

sub usage_text { 
    qq{ 
    $0 [--verbose|v]: 

    OPTIONS: 
     --verbose -v: be vebose 

    ARGUMENTS (subcommands): 
     on:   power on the device 
     off:  power off the device 
     reboot:  reboot the device 
     version: show PDU version 
     status:  show PDU status 
     sysstat: show PDU sysstatus 
    } 
} 

sub option_spec { 
    [ 'device|d=s'  => 'device name' ], 
    [ 'ip=s'   => 'ip address' ], 
    [ 'user|u=s'  => 'user name' ], 
    [ 'password|p=s' => 'password' ], 
    [ 'interval|i=s' => 'interval' ], 
    [ 'brand|b=s'  => 'brand' ], 
    [ 'community|c=s' => 'community' ], 
    [ 'version|v=s' => 'version' ], 
} 

sub command_map { 
    on  => 'Power::Control::Command::On', 
    off  => 'Power::Control::Command::Off', 
    reboot => 'Power::Control::Command::Reboot', 
    version => 'Power::Control::Command::Version', 
    status => 'Power::Control::Command::Status', 
    sysstat => 'Power::Control::Command::Sysstat', 
} 

sub command_alias { 
    r => 'reboot', 
    v => 'version', 
    st => 'status', 
    sys => 'sysstat', 
} 

our $opts; 
our $self; 
our $data; 

sub init { 
    ($self, $opts) = @_; 

    $data = $opts->{'ip'}; 
    print "\n The device name is $opts->{'device'}\n"; 
    print "\n The ip address is $data\n"; 
} 

print "\n The globla data is $data\n"; 
1; 

# ---- COMMAND: On ---- 
package Power::Control::Command::On; 
use base qw(CLI::Framework::Command); 

use strict; 
use warnings; 
use Power::Control; 
use Data::Dumper; 

print "\n The data from parent is $data \n"; 

sub usage_text { 
    q{ 
    on [--d=<device name>: Power on the device 
    } 
} 

#sub option_spec { 
# [ 'device|[email protected]' => 'device name' ], 
#} 

sub run { 

    print "\n This is the command on\n"; 
} 
1; 
+0

爲什麼不分開文件 - 每個文件一個模塊/函數?然後你的控制器模塊就可以進行system()調用。 –

+1

這聽起來像你正在訪問某個地方的錯誤範圍內的東西,但誰知道肯定?您發佈的代碼已混淆,部分內容似乎已被雙重粘貼或粘貼在缺失的行上。你可以清理代碼,然後告訴我們腳本中有什麼「'''pc'''」?這是您獲得有用回覆的唯一方法。 –

+0

我已更新我的帖子。添加了腳本電腦。 – user2476350

回答

0

感謝您關注此事。我花了一兩分鐘來組織和文件分割成一個典型的lib/Power/Control.pmlib/Power/Control/Command/On.pm佈局和清理一些東西,這是我得到的輸出:

[localhost ~/tmp%] perl stackex-pc --ip=127.0.0.1 --device=pants on 
The device name is pants 
The ip address is 127.0.0.1 
This is the command "on" 

我認爲這或多或少你想要什麼。我將在下面添加我對以下內容的解釋,但首先我將包含我的文件,然後您可以在家中嘗試。如果它有效,那麼你可以接受我的答案。如果我給出一個體面的解釋,然後其他人可以投我!首先,這裏的腳本:

#! /usr/local/bin/perl 
# 
# stackex-pc 
# Question: http://stackoverflow.com/questions/17054798 

use strict; 
use warnings; 

use lib 'lib' ; 
use Power::Control; 

# ---- EXECUTION ---- 
Power::Control->run(); # Launch command 

而這裏的包:

# lib/Power/Control.pm 
# Question: http://stackoverflow.com/questions/17054798 

package Power::Control; 
use base qw(CLI::Framework); 
use strict; 
use warnings; 

our ($data, $opts, $self); 

sub usage_text { 
    qq{ 
    $0 [--verbose|v]: 

OPTIONS: 
    --verbose -v: be vebose 

ARGUMENTS (subcommands): 
    on:   power on the device 
    off:  power off the device 
    reboot:  reboot the device 
    version: show PDU version 
    status:  show PDU status 
    sysstat: show PDU sysstatus 
    } 
} 

sub option_spec { 
    [ 'device|d=s'  => 'device name' ], 
    [ 'ip=s'   => 'ip address' ], 
    [ 'user|u=s'  => 'user name' ], 
    [ 'password|p=s' => 'password' ], 
    [ 'interval|i=s' => 'interval' ], 
    [ 'brand|b=s'  => 'brand' ], 
    [ 'community|c=s' => 'community' ], 
    [ 'version|v=s' => 'version' ], 
} 

sub command_map { 
    on  => 'Power::Control::Command::On', 
    off  => 'Power::Control::Command::Off', 
    reboot => 'Power::Control::Command::Reboot', 
    version => 'Power::Control::Command::Version', 
    status => 'Power::Control::Command::Status', 
    sysstat => 'Power::Control::Command::Sysstat', 
} 

sub command_alias { 
    r => 'reboot', 
    v => 'version', 
    st => 'status', 
    sys => 'sysstat', 
} 

sub init { 
    ($self, $opts) = @_; 

    print "\n The device name is $opts->{device}\n"; 
    print "\n The ip address is $opts->{ip}\n"; 
} 

1; 

如前所述我分開的文件在模塊的目錄型佈局,使有第二個文件。我爲了我自己的方便做了這個,所以不要覺得你必須做同樣的事情。

# lib/Power/Control/Command/On.pm                     
# Question: http://stackoverflow.com/questions/17054798 

package Power::Control::Command::On;   
use base qw(CLI::Framework::Command);  
use strict;                  
use warnings;                  
use Power::Control;                

sub usage_text {                 
    q{                   
    on [--d=<device name>: Power on the device 
    }                    
}                    

sub run {                  
    print "\n This is the command \"on\" \n"; 
    exit ; 
} 
1;   

我認爲你的第一種方法沒有奏效的原因是 - 就像錯誤信息指出的那樣 - 未初始化的變量。我試圖解釋如下:

  1. 我需要把use lib 'lib';use Power::Control;之前否則腳本不會有一個完整的@INC,無法找到Power::Control。當我解決這個問題時,我得到了和你一樣的錯誤。這表明你可能已經設置了你的CLI :: Framework,或者把你自己的模塊放在@INC的某處。

  2. 如果您在lib/Power/Control.pmour $data = "in the global scope";的第53行上更改"our $data ; - 否則未定義 - 您將在運行腳本時看到該消息。 「$ data」值沒有從init()子例程中設置如果在第012行中的第60行的init()子例程中用print "\n The ip address is $opts->{ip}\n";代替print "\n The ip address is $data\n";,那麼您將獲得更多預期的輸出。如果將$data =內部的init()更改爲my $otherdata = ...並相應地調整print行,您還將瞭解不同詞彙值對變量的影響。

  3. 我還沒有做完!我會審查/編輯我的解釋並添加一些關於變量範圍的參考,以及$data變量在CLI::Framework應用程序中正在執行的操作。

順便說一句,這是棘手的,但你可以通過簡單地將-d切換到命令運行在Perl調試腳本找出很多這樣的:

perl -d pc --ip=dsfa --device dsfasdf on

,然後通過腳本步進,因爲它運行,一味以變量值,追蹤等

如果您嘗試之前puttiing的on命令參數--ip=選項,你會看到另一種問題:命令行參數解析有點脆弱。您可能會添加一個優雅的檢查來修復此問題,或者至少使Failed parsing of command options更有意義(例如,將使用情況屏幕發送給用戶)。

祝您的項目順利。

相關問題