【问题标题】:expect Interact reads the matched line over and over again without moving onward期望 Interact 一遍又一遍地读取匹配的行而不继续前进
【发布时间】:2012-09-15 12:56:03
【问题描述】:

我有以下期望脚本:

  • SSH 到主机
  • 如果需要,接受用户的密码
  • 一旦ssh成功(出现提示),设置环境变量
  • 再次返回提示符后,运行程序进行网络测试
  • 再次返回提示符后,退出 expect 并关闭 ssh 会话
#!/usr/bin/expect
set hostname [lindex $argv 0]
set working_dir [lindex $argv 1]
set package [lindex $argv 2]
set tcl_test $working_dir/$package.tcl
set config $working_dir/$package.config
set logdir $working_dir/$package
set timeout 30
set prompt "\~\\\]\\\$"

eval spawn ssh $hostname
expect {
    -re "(yes/no)" {send "yes\r"}
    -re "password\:" {      
        interact {
            -o
            -re $prompt {send "export VARIABLE1=$working_dir\"\r"}
            -re $prompt {send "issue-test-command -config $config -module $tcl_test\r"}
        }
    }
}

密码匹配和交互工作正常。一旦 $prompt 匹配,就会发出环境变量导出命令:

-re $prompt {send "export VARIABLE1=$working_dir\"\r"}

这是正确的,但不是继续前进:

-re $prompt {send "issue-test-command -config $config -module $tcl_test\r"}

读取同一行,再次匹配模式并执行相同的命令。这会导致发出相同命令的永久循环。

如何强制交互移动到下一行,或者使用不同的内置期望来实现我所追求的?

【问题讨论】:

    标签: linux ssh command tcl expect


    【解决方案1】:

    想象你正在给某人下达指令:

    1. 如果看到红灯就停下来
    2. 如果你看到红灯就走

    如果他们感到困惑,您不会感到惊讶。这就是您对多个 -re $prompt 分支的期望所做的事情。然而,Expect 只接受你告诉它的第一条指令。

    试试这个:

        interact {
            -o
            -re $prompt {
                send "export VARIABLE1=\"$working_dir\"\r"
                send "issue-test-command -config $config -module $tcl_test\r"
            }
        }
    

    顺便说一句:

    1. exp_continuesend "yes\r" 之后消失了
    2. 您在 export 命令中发送了错误数量的双引号

    【讨论】:

    • 感谢您的信息,我现在已经完全按照我的意愿工作了。
    【解决方案2】:

    如果您多次提供相同的模式,则只会执行一个关联的分支。更复杂的事情必须完整地写出来(例如,用一个小状态机)。

    但我认为您使该代码过于复杂。您真正想要interact 的唯一地方是一旦您启动了程序,而您可能需要多臂expect 的唯一地方是在那个时候可能发生多种事情时互动。让我们写得更简单,但使用exp_continue。 (变量的设置我省略了……)

    eval spawn ssh $hostname
    # Manage the login sequence, with its optional host check and optional password
    # (that's optional in case someone decides to properly set up RSA keys)
    expect {
        -ex "(yes/no)" {      # Exact match here
            send "yes\r"
            exp_continue
        }
        -ex "password:" {     # Exact match here
            send "$password\r"
            exp_continue
        }
        -re $prompt {         # RE match here
            # Do nothing; fall out of the expect as we're now logged in...
        }
    }
    
    # We're now at a prompt; make things work as desired
    send "export VARIABLE1=\"$working_dir\"\r"
    expect -re $prompt
    send "issue-test-command -config $config -module $tcl_test\r"
    
    # Now we're ready to let the user talk to the program...
    interact
    

    【讨论】:

    • 感谢您的信息,也很有帮助
    猜你喜欢
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    • 2017-09-20
    相关资源
    最近更新 更多