0

Cisco デバイスにログインするための小さな Expect スクリプトを作成しました。ログインしたら、コマンドとgrep出力を繰り返し実行したいと思います。

#!/usr/bin/expect

send_user "Device name: "
expect_user -re "(.*)\n"
set host $expect_out(1,string)

send_user "Username: "
expect_user -re "(.*)\n"
set user $expect_out(1,string)

stty -echo
send_user -- "Password: "
expect_user -re "(.*)\n"
set pass $expect_out(1,string)
stty echo

send_user "show int "
expect_user  -re "(.*)\n"
set intf $expect_out(1,string)
send_user "\n"

spawn telnet $host
expect "Username:"
send "$user\r"
expect "Password:"
send "$pass\r"
expect ">"

この時点で、デバイスにログインしました。コマンド「show int xxx」を繰り返し実行し、特定の行の出力を grep します。grepExpect にも のようなコマンドもないので、特定の行からコマンドをsleep実行してループすることができます。このようにExpectとBashを混在させるにはどうすればよいですか?show intgrepping

更新: スクリプトはほぼ完成しました。この最後のハードルを乗り越えたら、完全なスクリプトを投稿します。行set bytesnow [exec grep "packets input" \< showint | cut -d \ -f 9]がエラーをスローしています。

child process exited abnormally
   while executing
"exec grep "packets input" < \showint | cut -d \  -f 9"

しかし、私が書いたテスト スクリプトでは問題なく動作します。ファイル ./showint があり、コマンド ラインでそのコマンドを実行すると正常に動作しますか? 何が問題なのかわかりませんか?

更新: さらなる調査 (http://wiki.tcl.tk/8489) によりgrep、ステータス コード 1 で終了することがわかりました。これは、パターンの一致が見つからなかったことを意味します。コマンドはコマンド ラインから正常に動作しますか? /full/path/to/showint でも。

END : 私は自分がいかに愚かであったかを理解することで間違いを修正しました。以下に回答します。助けてくれてありがとう :D

4

2 に答える 2

1

これは私がすることです

log_user 0
while(1) {
  send -- "sh int $intf | i packets input\r"
  set timeout 5
  expect {
    -re "^ +(\d+) packets" { send_user -- "$expect_out(1,string)" }
    timeout { send_user "broke?\n" }
  }
}

これにより、入力されたパケット数が取得されます。

于 2012-02-17T00:36:17.293 に答える
0

これは私の最初の Expect スクリプトです。その目的は、インターフェイスのライブ (ほぼ 1 秒!) スループットを提供することです。以下の例は、grep「packets input」を含む行を対象としているため、インターフェイスの入力速度を示しています。これを「パケット出力」に変更して、そのインターフェイスのライブ出力レートを取得します。

#!/usr/bin/expect

# Long delay for those tricky hostnames

set timeout 60

# Prompt user for device name/IP, username, password, 
# and interface to query (gi0/2)

send_user "Device name: "
expect_user -re "(.*)\n"
set host $expect_out(1,string)

send_user "Username: "
expect_user -re "(.*)\n"
set user $expect_out(1,string)

stty -echo
send_user "Password: "
expect_user -re "(.*)\n"
set pass $expect_out(1,string)
send_user "\n"
stty echo

send_user "show int "
expect_user  -re "(.*)\n"
set intf $expect_out(1,string)
send_user "\n"

spawn telnet $host
expect "Username:"
send "$user\r"
expect "Password:"
send "$pass\r"
expect ">"

set byteslast 0
set bytesnow 0

log_user 0

# Enter a continuous loop grabbing the number of bytes that
# have passed through an interface, each second.
# The different in this number each cycle, is essentially
# how much traffic this interface is pushing.

while { true } {
  send "show int $intf\r"
  expect ">"

  set showint [open "showint" "w"]
  puts $showint $expect_out(buffer)
  close $showint

  set bytesnow [exec grep "packets input" \< showint | cut -d \  -f 9]

  if { $bytesnow > $byteslast } {
    set diff [expr $bytesnow - $byteslast]
    set bps [exec expr "$diff" \* 8]
    set kbps [exec expr "$bps" \/ 1000]
  } elseif { $bytesnow < $byteslast } {
    set diff [expr $byteslast - $bytesnow]
    set bps [exec expr "$diff" \* 8]
    set kbps [exec expr "$bps" \/ 1000]
  } elseif { $bytesnow == $byteslast } {
    set kbps 0
  }

  set byteslast $bytesnow
  puts "$kbps Kbps\r"

  sleep 1
}

これは私の最初の Expect スクリプトであるため、もっと効率的かつ明確に記述できることは間違いありません (これは常に私が見つけたケースです)。:)

私のexec grepコマンドの問題は、その前に「showint」を開いたファイルを閉じておらず、別のファイルにアクセスしようとしていたことであることが判明しました。男子校生ミス!

于 2012-02-17T00:47:51.240 に答える