【问题标题】:How to send more than 100 cmd lines如何发送超过 100 条 cmd 行
【发布时间】:2018-08-21 20:49:46
【问题描述】:

我期望 (tcl) 脚本用于自动任务正常工作 - 通过 telnet/ssh 配置网络设备。大多数情况下要执行 1,2 或 3 个命令行,但现在我有 100 多个命令行要通过期望发送。我怎样才能以聪明和好的脚本方式实现这一点:) 因为我可以将超过 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
    }

附言我正在使用一种方法来获得成功,因为 cmd 行已成功执行,但我不确定这是完美的方法:D

【问题讨论】:

    标签: tcl expect


    【解决方案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
    }
    

    【讨论】:

    • 我遇到了一些问题。 foreach 循环效果很好,但我在它之后又放了一个期望:“expect '$prompt' {send 'copy run start'}” 有时会被吸走! (4 次工作 - 1 次没有,等等。)我认为是输出缓冲区的东西,因为进入循环,然后我等待同样的事情。你有改进的建议吗?我在 foreach 循环中写了一些解决方法,我在这里添加了一些想法:“send ''$cmd\r #marker $n” .. 然后等待同样的事情(不是 $prompt 而是 #marker $n)。但这是实际发送到设备#comment :(
    【解决方案2】:

    虽然可以,但您可以 send 这样使用长序列的命令,这通常是个坏主意,因为它会使整个脚本变得非常脆弱;如果发生任何意外情况,脚本只会继续强制脚本的其余部分结束。相反,最好有一个sends 序列和expects 穿插,以检查您发送的内容是否已被接受。发送一个很长的字符串的唯一实际情况是,当您在另一端创建一个函数或文件时,它将充当您调用的子程序;在那种情况下,没有真正有意义的地方停下来检查是否有中途提示。但那是个例外。

    请注意,您可以同时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"
    ...
    

    【讨论】:

    • 谢谢多纳尔。明天我会按你的方式安排:) 这就是你的意思: # Command-1 send "$command1\r" expect { -re {error: (.*)} { puts stderr "发生了一个问题: $expect_out(1,string)" exit 1 } "# " { } } # Command-2 send "$command2\r" expect { -re {error: (.*)} { puts stderr "一个问题发生了:$expect_out (1,string)" exit 1 } "# " { } } ...
    猜你喜欢
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2019-08-04
    • 2020-05-19
    • 2021-11-27
    • 2021-04-22
    • 2021-05-22
    相关资源
    最近更新 更多