如何发送100条以上的cmd行

时间:2018-08-21 20:49:47

标签: tcl expect

我希望(tcl)脚本能够使自动任务正常工作-通过telnet / ssh配置网络设备。在大多数情况下,需要执行1,2或3个命令行,但是现在我有100多个命令行可以通过Expect发送。我如何以一种聪明而又好的脚本方式实现这一目标:) 因为我可以将所有超过100个命令行连接到带有“ \ n”的变量“ commandAll”并一个接一个地“发送”,但是我认为这很丑陋:)是否有一种无需堆叠的方法它们一起在代码或外部文件中可读吗?

#!/usr/bin/expect -f
set timeout 20
set ip_address "[lrange $argv 0 0]"
set hostname "[lrange $argv 1 1]"
set is_ok ""

# Commands
set command1 "configure snmp info 1"
set command2 "configure ntp info 2"
set command3 "configure cdp info 3"
#... more then 100 dif commands like this !
#... more then 100 dif commands like this !
#... more then 100 dif commands like this !

spawn telnet $ip_address

# login & Password & Get enable prompt
#-- snnipped--#

# Commands execution

# command1
expect "$enableprompt" { send "$command1\r# endCmd1\r" ; set is_ok "command1" }
    if {$is_ok != "command1"} {
        send_user "\n@@@ 9 Exit before executing command1\n" ; exit
    }

# command2
expect "#endCmd1" { send "$command2\r# endCmd2\r" ; set is_ok "command2" }
    if {$is_ok != "command2"} {
        send_user "\n@@@ 9 Exit before executing command2\n" ; exit
    }

# command3
expect "#endCmd2" { send "$command3\r\r\r# endCmd3\r" ; set is_ok "command3" }
    if {$is_ok != "command3"} {
        send_user "\n@@@ 9 Exit before executing command3\n" ; exit
    }

p.s。给cmd行成功执行,我正在使用一种方法来贴脸,但我不确定那是完美的方法:D

2 个答案:

答案 0 :(得分:1)

不要使用数字变量,请使用列表

set commands {
    "configure snmp info 1"
    "configure ntp info 2"
    "configure cdp info 3"
    ...
}

如果命令已经在文件中,则可以将它们读入列表:

set fh [open commands.file]
set commands [split [read $fh] \n]
close $fh

然后遍历它们:

expect $prompt

set n 0
foreach cmd $commands {
    send "$cmd\r"
    expect {
        "some error string" {
            send_user "command failed: ($n) $cmd"
            exit 1
        }
        timeout {
            send_user "command timed out: ($n) $cmd"
            exit 1
        }
        $prompt 
    }
    incr n
}

答案 1 :(得分:0)

是的,您可以这样send较长的命令序列,通常不是一个好主意,因为这会使整个脚本非常脆弱;如果发生任何意外情况,脚本将继续强制其余脚本结束。相反,最好将send插入expect序列,以检查您发送的内容是否已被接受。传送长字符串的唯一真实案例是在另一端创建要用作子程序的函数或文件时;在这种情况下,没有真正有意义的地方可以停下来检查是否有提示。但这是例外。

请注意,您可以一次expect做两件事;这通常非常有用,因为它可以让您直接检查错误。我之所以这样说是因为它是一种经常被忽略的技术,但是它却使您的脚本更加健壮。

...
send "please run step 41\r"
expect {
    -re {error: (.*)} {
        puts stderr "a problem happened: $expect_out(1,string)"
        exit 1
    }
    "# " {
        # Got the prompt; continue with the next step below
    }
}
send "please run step 42\n"
...