【问题标题】:Conditions in Expect script causing it to hangExpect 脚本中的条件导致它挂起
【发布时间】:2021-04-29 04:08:45
【问题描述】:

我正在使用期望脚本(在 bash 脚本中)通过 ssh 进入远程服务器并执行脚本,本地服务器将知道远程服务器的脚本已完成,因为它(远程)将回显“完成”在执行结束。

但是,脚本可以位于三个位置之一,因此我设计了以下期望脚本,尽管在代码示例中它成功执行了远程服务器脚本 - 它无法检测到打印的“完成”并因此挂起.

本地服务器期望脚本:

versionScriptLoc1="/path/to/script1"
versionScriptLoc2="/path/to/script2"
versionScriptLoc3="/path/to/script3"
expect <<-EOS |& tee logfile.${hostname}.log
        #!/usr/bin/expect
        set timeout $EXP_TIMEOUT
        puts "\nLogging into remote host via SSH..\n"
        spawn ssh -q -tt -o ConnectTimeout=$SSH_TIMEOUT -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${hostname}
        expect "*assword*"
        send -- "$secret\r"
        expect {
                "*assword*" {
                        send \x03
                        puts "\nIncorrect Password\n"
                        exit 1
                }
                "$prompt" {
                        send -- "/usr/seos/bin/sesu - $user\r"
                        expect "*assword*"
                        send -- "$secret\r"
                        expect "$prompt"
                        send -- "${versionScriptLoc1}\r"
                        expect {
                                "finished" {

                                }
                                "No such file or directory" {
                                        puts "Location 1 execution Failed"
                                        send -- "${versionScriptLoc2}\r"
                                        expect {
                                                "No such file or directory" {
                                                        puts "Location 2 execution Failed"
                                                        send -- "${versionScriptLoc3}\r"
                                                }
                                        }
                                        exp_continue
                                }
                        }
                        send -- "exit\r"
                        expect "$prompt"
                        send -- "exit\r"

                }
        }
        expect eof
        exit 0
EOS

我认为 exp_continue 会进行期望循环并寻找“完成”。在上面的代码中,脚本位于位置 2,它成功触发了,但是即使打印了“finished”,它仍然挂起。

任何关于它为什么挂起/可能是更好的设计的帮助将不胜感激。

PS:我知道我应该生成脚本而不是像用户一样触发它们,但我过去尝试过但没有成功。

【问题讨论】:

    标签: bash expect


    【解决方案1】:

    我建议你不要将期望的代码写得嵌套太深。

    问题是,在运行 script2 之后,你点击 exp_continue 是否 你成功与否。太糟糕了,期望没有exp_breakgoto.

    因此需要进行一些重组。我正在使用一些布尔变量来 管理控制流。

    由于我已经引入了一些 Tcl 变量,它将使 shell 分离 来自 tcl vars 的 vars 更难。我们将 shell vars 变成 环境变量,并引用heredoc:

    # ...
    export EXP_TIMEOUT SSH_TIMEOUT
    export hostname user secret prompt
    export versionScriptLoc1 versionScriptLoc2 versionScriptLoc3
    
    expect <<'EOS' 2>&1 | tee "logfile.${hostname}.log"
    
        set timeout $env(EXP_TIMEOUT)
        puts "\nLogging into remote host via SSH..\n"
    
        spawn ssh -q -tt -o ConnectTimeout=$env(SSH_TIMEOUT) -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $env(hostname)
        expect "*assword*"
        send -- "$env(secret)\r"
    
        expect {
            "*assword*" {
                send \x03
                puts "\nIncorrect Password\n"
                exit 1
            }
            "$env(prompt)"
        }
    
        send -- "/usr/seos/bin/sesu - $env(user)\r"
        expect "*assword*"
    
        send -- "$env(secret)\r"
        expect "$env(prompt)"
    
        set run2 false
        send -- "$env(versionScriptLoc1)\r"
        expect {
            "No such file or directory" {
                puts "Location 1 execution Failed"
                set run2 true
            }
            "finished"
        }
    
        set run3 false
        if {$run2} {
            send -- "$env(versionScriptLoc2)\r"
            expect {
                "No such file or directory" {
                    puts "Location 2 execution Failed"
                    set run3 true
                }
                "finished"
            }
        }
    
        if {$run3} {
            send -- "$env(versionScriptLoc2)\r"
            expect {
                "No such file or directory" {
                    puts "Location 3 execution Failed"
                }
                "finished"
            }
        }
    
        send -- "exit\r"
        expect "$env(prompt)"
    
        send -- "exit\r"
    
        expect eof
        exit 0
    EOS
    

    【讨论】:

      猜你喜欢
      • 2014-07-05
      • 2013-02-08
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-16
      • 1970-01-01
      • 2010-09-16
      相关资源
      最近更新 更多