Perl:输出检查例程返回错误状态

时间:2014-03-20 08:06:58

标签: perl scripting

美好的一天,大家!

我在Perl中几乎无知,但必须处理一个脚本,该脚本旨在处理Celerra NAS的几个系统检查命令的输出。其中一个例程总是在$ rc变量中返回“2”,而据我所知,它应该是“0”。

以下是用于处理输出的脚本部分:

#(7) Subroutine to handle 'enclosure_status -v -e 0'
#    Sample command output:
# DEVICE A                         DEVICE B
#---------------ENCLOSURE ALARMS----------------
# Pass        PSA OK               Pass
sub enclosure_status {
#   Find column positions given variable word count, space delimited output
    $deva_ix=index($result[1],"DEVICE A");  
    $devb_ix=index($result[1],"DEVICE B");  
    $msg="";
    $rc=-1;
    $skip=1;    # skip items other than alarms & errors
    foreach (@result) {
    if ($deva_ix eq -1) { last; }   # command output not as expected
    if (length($_) < $devb_ix+4) { next; }      # blank line
    if ($_ =~ m/------/) {      # process block header
        if ($rc eq -1) { $rc=0; }
        if ($_ =~ /ALARM/) { $skip=0; next; }
        if ($_ =~ /ERRORS/) { $skip=0; next; }
        if ($_ =~ /FRU STATUS/) { $skip=0; next; }
        $skip=1; next; }
    if ($skip eq 1) { next; }
        if (substr($_,$deva_ix,4) eq "Pass" 
        and substr($_,$devb_ix,4) eq "Pass") { next; }
        $rc=2;
        if ($msg ne "") { $msg = $msg . ", "; }
    $msg = $msg . $_;
        } # end foreach
    if ($rc eq 0) {
        $msg="All alarms are in condition Pass"; }
    elsif ($rc<0) {
        $rc=3; $msg="Unexpected results from command " . $parm[1]; }
    &print_results($host,$parm[0],$rc,$msg);
    } # end subroutine

这是命令输出的一部分:

    DEVICE A                         DEVICE B
-------------------PRESENCE--------------------
 00 60 16 43 C7 EB    MAC     00 60 16 43 C9 85
 Scorpion    Hardware Platform    Scorpion
 Present     Peer Compute Blade   Present
 Present     Compute Blade        Present
 Powered On  Compute Blade        Powered On
 Present     Power Supply A       Present
 Present     Power Supply B       Present
 Inactive    Manufacturing Mode   Inactive
 Inactive    Margin High Mode     Inactive
 Inactive    Margin Low Mode      Inactive
 Inactive    MP I2C Bus in Reset  Inactive
---------------BROADCOM STATUS-----------------
 Active      Dnlink/P4 FullDuplex Active
 Active      Dnlink/P4 100 MBPS   Active
 Active      Dnlink/P4 Up         Active
 Active      PeerSP/P3 FullDuplex Active
 Active      PeerSP/P3 100 MBPS   Active
 Active      PeerSP/P3 Up         Active
 Active      Uplink/P1 FullDuplex Active
 Active      Uplink/P1 100 MBPS   Active
 Active      Uplink/P1 Up         Active
 Active      SP    /P0 FullDuplex Active
 Active      SP    /P0 100 MBPS   Active
 Active      SP    /P0 Up         Active
---------------ENCLOSURE ALARMS----------------
 Pass        PSA OK               Pass
 Pass        PSA Overtemp         Pass
 Pass        PSA AC OK            Pass
 Pass        PSB OK               Pass
 Pass        PSB Overtemp         Pass
 Pass        PSB AC OK            Pass
----------------BROADCOM ALARMS----------------
 Pass        5325 Comm Status     Pass
 Pass        5325 MIB RAM         Pass
 Pass        5325 MIN MEM         Pass
 Pass        5325 BUFF Con        Pass
--------------RESUME CSUM ERRORS---------------
 Pass        PSA Csum Error       Pass
 Pass        PSB Csum Error       Pass
 Pass        CB x Csum Error      Pass
 Pass        Midplane Csum Error  Pass
 Pass        Resume Read Timeout  Pass
----------------COLDFIRE ALARMS----------------
 Pass        P On Self Flash Status Pass
 Pass        P On Self RAM Status  Pass
 Pass        P On Self FEC Status  Pass
 Pass        P On Self 5325 Status  Pass
 Pass        Run Self Flash Status  Pass
 Pass        Run Self RAM Status  Pass
 Pass        Diag 5325 Status     Pass
 Pass        Encl Resume Block    Pass
 Pass        Peer RS232 traffic   Pass
 Pass        MidPlane ID Read     Pass
 Pass        I2C Arbit Error      Pass
 Pass        I2C MP Bus Error     Pass
-------------STATUS CONDITIONS-----------------
 Valid       Peer Coldfire Status Valid
 Valid       Fault Expander       Valid
 Valid       Data Mover Status    Valid
 Valid       PSB Status           Valid
 Valid       PSA Status           Valid
------------------FRU STATUS-------------------
 Pass        FRU CPU DIMM 0       Pass
 Pass        FRU CPU DIMM 1       Pass
 Pass        FRU CPU DIMM 2       Pass
 Pass        FRU CPU DIMM 3       Pass
 Pass        FRU CPU Module       Pass
 Pass        FRU CPU IO Module    Pass
 Pass        NAS Personality Card Pass
 Pass        FRU Enclosure        Pass
 Pass        FRU Coldfire         Pass
 Pass        FRU Power Supply B   Pass
 Pass        FRU Power Supply A   Pass
---------------SYSTEM VARIABLES----------------
 02          Slot ID              03
 00          Enclosure ID         00
 00          BackPlane ID         01
 61          Post Code            61
 05          Reason Code          05
 2C          Blade Status Code    2C
 80          Post Middle 8 bits   80
 00          I2C Error Mask       00
 00          I2C MP Error Mask    00

脚本形成一条要发送到服务器的消息,它的外观如下:

emcns120        Alarms  2        Pass P On Self Flash Status Pass, Pass P On Self RAM Status Pass, Pass P On Self FEC Status Pass, Pass P On Self 5325 Status Pass, Pass Run Self Flash Status Pass

非常感谢任何帮助!

鲍里斯

2 个答案:

答案 0 :(得分:0)

嗯......似乎有一些名为@result的数组希望包含字符串。对于这些字符串中的每一个,您检查从$deva_ix$devb_ix开始的两个四个字母子字符串是否等于字符串"Pass",如果,即使一次,也不等于,{end} { {1}}等于2。

奇怪的是,$rc$deva_ix被设置为$devb_ix中第二个字符串中的子字符串"DEVICE A""DEVICE B"的位置。虽然包含@result的标题和标题中没有------"ALARM""ERROR"的标题会被跳过,但您的示例文件(我只是假设这些行存储在"FRU STATUS"中)不完整或不兼容,因为它的第二行没有设备名称。

答案 1 :(得分:0)

这里的问题是你假设通过/失败状态 总是在同一列中被违反。如果你仔细看 你的COLDFILE ALARMS,你会在某些情况下看到最终状态 被空间推出,导致你的日常失败。

我建议在你的部分中分隔空格 关心并始终比较 该行中的第一个单词和带有“Pass”的最后一个单词以查看是否 一切都是正确的。这是更新后的代码:

sub enclosure_status {
$msg="";
$rc=-1;
$skip=1;    # skip items other than alarms & errors
foreach (@result) {
if ($_ =~ m/------/) {      # process block header
    if ($rc eq -1) { $rc=0; }
    if ($_ =~ /ALARM/) { $skip=0; next; }
    if ($_ =~ /ERRORS/) { $skip=0; next; }
    if ($_ =~ /FRU STATUS/) { $skip=0; next; }
    $skip=1; next; }
if ($skip eq 1) { next; }
@words = split;
if ($words[0] eq "Pass" && $words[-1] eq "Pass") { next; }
    $rc=2;
    if ($msg ne "") { $msg = $msg . ", "; }
$msg = $msg . $_;
    } # end foreach
if ($rc eq 0) {
    $msg="All alarms are in condition Pass"; }
elsif ($rc<0) {
    $rc=3; $msg="Unexpected results from command " . $parm[1]; }
&print_results($host,$parm[0],$rc,$msg);
} # end subroutine

我试图坚持你的风格。