混合期望和BASH

时间:2012-02-16 21:34:00

标签: bash automation expect cisco

我写了一个小的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?

UPDATE :我现在已经完成了这个脚本,一旦我克服了最后一个障碍,我就会发布完整的脚本。第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。

结束:我通过意识到我曾经是个傻瓜来解决我的错误,在下面回答。谢谢大家的帮助:D

2 个答案:

答案 0 :(得分: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" }
  }
}

这将为您提供输入的数据包数量。

答案 1 :(得分: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”,我没有关闭,我试图访问另一个文件;男生错误!