【问题标题】:Expect: "missing close-brace" and send command failure期望:“缺少右括号”并发送命令失败
【发布时间】:2021-02-07 16:51:39
【问题描述】:

我正在尝试运行一个通过 SSH 连接到另一个本地设备以安装和运行 python 脚本的期望脚本。 所有变量都在脚本之外定义:

set prompt "$SSHuser@$SSHname:~$"
spawn ssh -o \"StrictHostKeyChecking no\" $SSHuser@$SSHhost
expect
{
  "*assword"
  {
    send "$SSHpassword\r"
    exp_continue
  }
  "$prompt"
  {
    send "sudo su"
    expect
    {
      "*assword"
      {
        send "$SSHpassword\r"
        exp_continue
      }
      "$prompt"
      {
        send "apt update && apt upgrade -y && apt install net-tools -y && apt install python3-pip -y"
        expect "$prompt"
        {
        send "wget -O script.py https://SOMEURL"
        }
      }
    }
  }
}

但是,我不断收到以下输出/错误:

missing close-brace
    while executing
"{"
couldn't read file "sur
    expect
    {
      *assword
      {
        send REDACTEDPASSWORD
        exp_continue
      }
      
      {
        send -- apt": no such file or directory
spawn ssh -o StrictHostKeyChecking no USERNAME@192.168.1.173
USERNAME@192.168.1.173's password: 

我计算了括号并使用了突出显示工具,我没有看到任何丢失的括号。 我也不明白为什么它一直把 "send "sudo su\r" 读作 "sur"。 我的期望仍然非常有限。 如果能帮助我理解这里出了什么问题,我将不胜感激。

【问题讨论】:

  • 您需要在expect 行的末尾添加一个反斜杠,以便将下一行视为同一命令的一部分。有关如何解析 tcl 的详细信息,请参阅tcl.tk/man/tcl8.6/TclCmd/Tcl.htm
  • 我不确定你是否也可以嵌套 expect 这样的调用,但总的来说我对 tcl 的熟悉程度比预期的要高。
  • 你考虑过使用ansible吗?有诸如 expect 或 apt 之类的 ansible 模块。使用 ansible,您可以使用 ssh-coonconnections 在远程机器上执行 python 脚本。见docs.ansible.com/ansible/latest/collections/ansible/builtin/…
  • 如果你使用SSH公钥认证并正确设置sudo,就不需要再使用expect了。
  • 看看我的sexpect (Expect for Shells),您可以使用它来编写仅使用shell 代码的Expect 脚本。

标签: bash shell ssh expect


【解决方案1】:

Tcl 强制您使用the "one true brace style",因为换行符是命令终止符。

作为注释,expect 代码不必嵌套得那么深。这段代码可以写成

set prompt "$SSHuser@$SSHname:~$"

spawn ssh -o "StrictHostKeyChecking no" $SSHuser@$SSHhost
expect {
  "*assword" {
    send "$SSHpassword\r"
    exp_continue
  }
  "$prompt"
}

send "sudo su"
expect {
  "*assword" {
    send "$SSHpassword\r"
    exp_continue
  }
  "$prompt"
}

send "apt update && apt upgrade -y && apt install net-tools -y && apt install python3-pip -y"
expect "$prompt"

send "wget -O script.py https://SOMEURL\r"
expect "$prompt"

# assuming you want to exit here
send "exit\r"
expect eof

基本上,每个 spawn 或 send 都应该跟一个 expect。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-04
    • 2015-03-31
    • 2018-04-10
    • 1970-01-01
    相关资源
    最近更新 更多