0

我写了一个小的 Expect 脚本来登录 Cisco 设备;登录后,我想重复运行命令和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特定行的输出。grep不在 Expect 中,也没有类似的命令sleep,所以我可以循环执行show int命令,grepping在我的特定行之外。我怎样才能像这样混合 Expect 和 Bash?

更新:我现在几乎完成了脚本,一旦我克服了最后一个障碍,我将发布完整的脚本。一行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为包含“数据包输入”的行。将其更改为“数据包输出”以获得该接口的实时输出速率。

#!/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 回答