2015-09-15 72 views
0

嘗試從bmp中將snmpget的輸出轉換爲數組。 目的是查詢SAN設備的SNMP狀態。 SNMPGET命令行是如下從snmpget輸出到bash陣列

# /usr/bin/snmpget -v2c -Oqv -c public nas.mynetwork.lcl .1.3.6.1.4.1.9804.3.1.1.2.1.30.0 .1.3.6.1.4.1.9804.3.1.1.2.1.39.0 

,其輸出是一樣

"P4500G2" 
"12 600GB SAS 3.0Gbps drives" 

我打算用這一個腳本,所以我讓整個命令行的變量。這是腳本,將其輸出發送到一個新的數組變量,然後遍歷數組。從上面的腳本

# Paths and options 
SNMPGET='/usr/bin/snmpget' 
SNMPOPTIONS='-v2c -Oqv -c public' 
SNMPHOST='nas.mynetwork.lcl' 
SNMPOID1='.1.3.6.1.4.1.9804.3.1.1.2.1.30.0' 
SNMPOID2='.1.3.6.1.4.1.9804.3.1.1.2.1.39.0' 

# Run the command, strip quotes and leave output in variable SNMPREPLY 
SNMPREPLY=($($SNMPGET $SNMPOPTIONS $SNMPHOST $SNMPOID1 $SNMPOID2 | tr -d '"')) 

# Check what's in the array 
for index in ${SNMPREPLY[*]} 
do echo $index 
done 

輸出是這

P4500G2 
12 
600GB 
SAS 
3.0Gbps 
drives 

正如你所看到的報價是正確不見了如預期,但是從SNMPGET每句話都放在一個單獨的數組項。這不是目的,而是將每個輸出行保存爲一個單獨的數組項。

試圖查看bash IFS變量,但無論如何都無法使其工作。

我在做什麼錯?

回答

0

更容易一行一行讀取輸出並將其追加到數組中,而不是一次嘗試捕獲它。

while IFS= read -r line; do 
    snmpreply+=("$line") 
done < <($SNMPGET $SNMPOPTIONS $SNMPHOST $SNMPOID1 $SNMPOID2 | tr -d '"') 

在這裏,我們重定向用於從工藝取代環(以及因此read命令)標準輸入。 <(...)中命令的輸出被視爲是文件。它類似於使用管道

snmp ... | while IFS= read -r line; do 
    ... 
done 

的,除了它確保循環在當前shell中運行,所以你在循環生成數組仍然是可用的,一旦退出循環。

(如果使用bash 4,可以替換爲readarray命令的循環:

# -t strips the newlines from each line 
readarray -t snmpreply < <($SNMPGET ...) 

當陣列上進行迭代,使用@代替*和引用的擴大,保護空白。

for item in "${snmpreply[@]}" 
do echo "item" 
done 

其他一些注意事項:

  1. 不要使用您的變量全部大寫的名稱;那些是保留的。

    snmpget='/usr/bin/snmpget' 
    snmpoptions='-v2c -Oqv -c public' 
    snmphost='nas.mynetwork.lcl' 
    snmpoid1='.1.3.6.1.4.1.9804.3.1.1.2.1.30.0' 
    snmpoid2='.1.3.6.1.4.1.9804.3.1.1.2.1.39.0' 
    
  2. 使用數組來存儲用於命令多個選項。您可以將所有的參數保存在同一陣列中便於調用的:

    snmpoptions=(-v2c -0qv -c public # your original options 
           nas.mynetwork.lcl  # the host 
           .1.3.6.1.4.1.9804.3.1.1.2.1.30.0 # oid1 
           .1.3.6.1.4.1.9804.3.1.1.2.1.39.0 # oid2 
          ) 
    

    當調用命令,所有報價參數擴展:

    "$snmpget" "${snpoptions[@]}" 
    
+0

謝謝,這工作。 我不完全理解第一個代碼塊,以及它爲什麼起作用。但是會研究它並嘗試理解。乍一看,我認爲它是逐行讀取$ SNMPGET輸出並將其附加到snmpreply變量。尼斯。 – tompaah

+0

我將擴展使用進程替換語法('<(...)')。 – chepner

0

IFS是正確的路要走。

OIFS=$IFS 
IFS=$'\n' 
f() { echo "'P4500G2'"; echo "'12 600GB SAS 3.0Gbps drives'"; } 
f 
'P4500G2' 
'12 600GB SAS 3.0Gbps drives' 

a=($(f)) 
for i in ${a[*]}; do echo $i ; done 
'P4500G2' 
'12 600GB SAS 3.0Gbps drives' 

IFS=$OIFS 
for i in ${a[*]}; do echo $i ; done 
'P4500G2' 
'12 
600GB 
SAS 
3.0Gbps 
drives' 
+0

謝謝,但我不明白的地方在我應該把它寫下來。如果在命令SNMPREPLY = ....之前立即插入它,命令會失敗,並顯示「在-v標誌後指定的無效版本:2c -Oqv -c public」 – tompaah

+0

事實上,在循環數組之前應將其置入。 – aayoubi