2012/07/30

Control variables by array in Expect 在Expect 內利用陣列去控制變數

Procedures and variables that used in numerous scripts can be stored in separate files. Thus user can open variable file and change the variable directdly by real case, but not change the script. In this case, I will demo 2 topic. One is using source command to read variable or libary file, another one is controlling variables by array.

在多個script內使用的函式和變數可以儲存在獨立的檔案中,如此,使用者可以依照實際情況直接開啟檔案並修改變數,而不需要改變 script 。在這個範例中,我會示範2個主題:一個是使用source指令讀取變數檔或函式庫,另一個是利用陣列控制變數。

Manual Operation 手動操作


I would like to check the current status, 2a 6f 00 01, of first CPU (IPMB ID: 0x72) in device 10.0.1.220.

我希望能確認某個在10.0.1.220設備內第一張CPU (IPMB ID: 0x72)的目前狀態 2a 6f 00 01。

jose@QA:~$ ipmitool -I lan -H 10.0.1.220 -U admin -P admin -A none -t 0x72 -b 7 raw 0x2e 0x0d 0x2a 0x6f 0x00
2a 6f 00 01
jose@QA:~$


In fact, This equipment can be installed up to 10 CPU cards. The sequence of IPMB ID is as below.

事實上,這個設備最多可以安裝 8 張 CPU 卡,其順序與 IPMB ID 如下:

No. IPMB ID
1 0x72
2 0x74
3 0x76
4 0x78
5 0x7a
6 0x7c
7 0x7e
8 0x80

To get different statu of cards, user could change the IPMB ID in command line by real case.

使用者可以依照實際的插卡情況調整命令列中的 IPMB ID 以取得不同卡的狀態。

Variable file 變數檔


User could modify the card No. by "variable.exp" file which stored variable by rela case. The content as below.

使用者可以藉由 variable.exp 檔案儲存變數,並依照插卡的實際情況調整實際的 card 編號,其內容如下:

set CPU_SLOT { 1 3 6 8}
set IPMB_ADDR {0x72 0x74 0x76 0x78 0x7a 0x7c 0x7e 0x80}
set TARGET_IP "10.0.1.220"
log_user 1


Code 程式


The goal of this code is catch the "2a 6f 00 01" value by array in Expect to confirm the status of each card.

這個程式的目標是要在 Expect 中透過陣列的方式取得「2a 6f 00 01」值以確認每一張卡的狀態。

spawn /bin/bash
source variable.exp
set cpu_slot $CPU_SLOT
set ipmb_addr $IPMB_ADDR
set target_ip $TARGET_IP

set send_slow {1 .01}

foreach {cpu} "$cpu_slot" {

# Step 1
set step "Transfer to Device ID from real Card Slot"
set tmp_ipmb_id [lindex $ipmb_addr [expr $cpu -1]]
# puts "IPMB ID = $tmp_ipmb_id"

# Step 2
set step "ipmitool -I lan -H $target_ip -U admin -P admin -A none -t $tmp_ipmb_id -b 7 raw 0x2e 0x0d 0x2a 0x6f 0x00"
expect {
"jose@" { send -s "ipmitool -I lan -H $target_ip -U admin -P admin -A none -t $tmp_ipmb_id -b 7 raw 0x2e 0x0d 0x2a 0x6f 0x00\r" }
}

# Step 3
set step "Check $target_ip CPU$cpu status"
expect {
" 2a 6f 00 01" { send -s "\r"; puts "$step Pass." }
}

}


The first part of this script, I used the content of another file by source command. To distinguish the difference between local-script variable and external-file variable, I transfered the variable from upper case (ex. CPU_SLOT) to lower case (ex. cpu_slot).

在這個 script 的第一個部份,我透過 source 命令使用其他檔案的內容,我特地轉換了外部檔案內設定的變數(CPU_SLOT)成為 script 內可以使用的變數(cpu_slot),以區別 script 內的變數和外部檔案的變數。

Besides, I used "send_slow" variable to contorl the slowness of send command. The first is the number of characters to send at a time. The second number is a time to pause after each group of characters is sent. In this case, {1 .01} means send 1 character every 0.01 second.

此外,我使用了 send_slow 變數控制以減緩 send 命令輸入的速度。第一個數值是單位時間內輸入的字符數,第二個數值是輸入每個位元數群組所要暫停的時間,在這個案例中,{1 .01} 表示每0.01秒輸入1個字符。

In the foreach loop, the first argument "cpu" is a variable name. Upon each iteration of the loop, the variable is set to the next element "$cpu_slot" in the list. Than I used expr command to transfer data type and calculate the index number, and get the data by index in array "ipmb_addr".

在 foreach 廻圈中,第一個參數 cpu 是一個變數的名稱,依據迴圈的每一個循環,這個變數被列中的第二個元素 $cpu_slot 設定,我接著使用 expr 命令轉換資料的類型並計算索引值,並藉由索引值取出陣列 ipmb_addr 的值。

log 執行結果


The log of processing as below.

執行的結果如下:

jose@QA:~$ expect test2.exp
spawn /bin/bash
jose@QA:~$ ipmitool -I lan -H 10.0.1.220 -U admin -P admin -A none -t 0x72 -b 7 raw 0x2e 0x0d 0x2a 0x6f 0x00
2a 6f 00 01
jose@QA:~$ Check CPU1 status Pass.

jose@QA:~$ ipmitool -I lan -H 10.0.1.220 -U admin -P admin -A none -t 0x76 -b 7 raw 0x2e 0x0d 0x2a 0x6f 0x00
Unable to send RAW command (channel=0x7 netfn=0x2e lun=0x0 cmd=0xd)
jose@QA:~$ ipmitool -I lan -H 10.0.1.220 -U admin -P admin -A none -t 0x7c -b 7 raw 0x2e 0x0d 0x2a 0x6f 0x00
2a 6f 00 01
jose@QA:~$ Check CPU6 status Pass.

jose@QA:~$ ipmitool -I lan -H 10.0.1.220 -U admin -P admin -A none -t 0x80 -b 7 raw 0x2e 0x0d 0x2a 0x6f 0x00
2a 6f 00 01
Check CPU8 status Pass.
jose@QA:~$


Change log_user variable 改變 log_user 變數


By change "log_user 0" to the "variable.exp" file and giving the final expect command an explicit action, the output is simplified dramatically as below.

藉由改變 variable.exp 檔案內的 log_user 0,可以僅取得 expect 命令的明確動作,其輸出結果大輻簡化如下:

jose@QA:~$ expect test2.exp
spawn /bin/bash
Check 10.0.1.220 CPU1 status Pass.
Check 10.0.1.220 CPU6 status Pass.
Check 10.0.1.220 CPU8 status Pass.
jose@QA:~$

沒有留言:

張貼留言