Linux

在 Expect 腳本中將字元串與子字元串匹配

  • April 4, 2017

我有這樣的輸出:

Node Name                     Status        IP Address
======================================================
bw2acn0                      ENABLED      x.x.x.x
bw2acn1                      ENABLED     x.x.x.x
bw2dvn0                      ENABLED     x.x.x.x
bw2dvn1                      ENABLED     x.x.x.x
bw2vm0                       ENABLED      x.x.x.x
bw2vm1                       ENABLED      x.x.x.x

我想創建一個循環來查看這個輸出是否包含任何應用程序的名稱。

#!/opt/tools/unsupported/expect-5.39/bin/expect

set HOST [ lindex $argv 0 ]
set USER [ lindex $argv 1 ]
set PASSWORD [ lindex $argv 2 ]
set APP1 [ lindex $argv 3 ]
set APP2 [ lindex $argv 4 ]
set APP3 [ lindex $argv 5 ]
set APP4 [ lindex $argv 6 ]

spawn ssh -l $USER $HOST
expect_after eof {exit 0}
set timeout 120

expect "password:" { send "$PASSWORD\r" }

expect "~]#" { set buff $expect_out(buffer)
foreach i $APPS {
    if {[regexp {"${i}"} $buff]} {
   log_file ../report.txti
           send_log "Commit nodes on $i ------------------------------- Passed\n\n"
           puts "*********************paased"
   } else {
   log_file ../report.txt
           send_log "Commit nodes on $i ------------------------------ Failed\n\n"
           puts "******************failed"
       }

}
}
log_file
send "\r"

expect "~]#" { send "date\r" }
expect "~]#" { send "exit\r" }

但我得到的只是它失敗了,儘管它應該通過。

if { $buff match {*$APP$i*} } {

是什麼match文件中沒有使用該術語的任何內容。expr還有APP變數是從哪裡來的?你有APP1等等,但沒有APP

string命令組可以將字元串與string match, 和array(其他語言稱為散列或關聯數組)匹配可能更好地對應用程序(節點?)名稱進行分組,而不是嘗試使用變數作為變數名:

set theapps(app1) foo
set theapps(app2) bar
set theapps(app3) zot

set buff "blah bar blah"

foreach {name value} [array get theapps] {
   if {[string match "*$value*" $buff]} {
       puts "ok - $name $value"
   } else {
       puts "not ok - $name $value"
   }
}

執行時,這匹配barapp2

$ tclsh choices
not ok - app3 zot
not ok - app1 foo
ok - app2 bar
$ 

第二種選擇是使用要搜尋的項目列表。這可以通過將非應用程序名稱從參數中移出,然後遍歷其餘項目來完成:

proc shift {list} {
   set result ""
   upvar 1 $list ll
   set ll [lassign $ll result]
   return $result
}

set HOST [shift argv]
set USER [shift argv]
set PASSWORD [shift argv]

puts "leading args: >$HOST< >$USER< >$PASSWORD<"

set buff "blah bar blah"

foreach substr $argv {
   if {[string match "*$substr*" $buff]} {
       puts "match >$buff< on >$substr<"
   }
}

引用自:https://unix.stackexchange.com/questions/355618