【问题标题】:expect script stop after sending \003发送 \003 后期望脚本停止
【发布时间】:2015-11-19 09:43:15
【问题描述】:

在无法继续的期望脚本上需要一些帮助。该脚本的功能是连接远程主机,更改用户然后运行命令。但是我放置了一个 else 语句,当更改用户提示更新密码时,它将跳过该语句并在下一个主机上继续。但是脚本在我发送 \003 的地方停止。期望脚本如下所示;

#!/usr/bin/expect -f
set i [open "eposhosts"]
set hosts [split [read -nonewline $i] "\n"]

foreach host $hosts {
spawn /usr/bin/ssh -q appadm@$host
expect "appadm@$host:~>"
send "su epos\r"
expect "Password:"
send "password\r"
expect {
"epos@$host:/home/appadm>" {send "grep playlist /appl/epos/bin/cron.epos\r"; exp_continue}
"(current) UNIX password:" {send "\003"; exp_continue}
}
expect {
"epos@$host:/home/appadm>" {send "exit\r"; exp_continue}
"[appadm@$host ~]" {send "exit\r"}
}
expect "appadm@$host:~>"
send "exit\r"
expect eof
}

【问题讨论】:

  • 脚本停止是什么意思?究竟会发生什么?期望脚本完全退出?
  • 是的,expect 脚本错误退出
  • 出现错误退出?真的吗?什么错误?
  • 它没有说太多,但错误输出低于无效命令名称“appadm@i200135”,同时执行从“expect {”epos@$host:/home/ 中调用的“appadm@$host ~” appadm>" {send "exit\r"; exp_continue} "[appadm@$host ~]" {send "exit\r"} }" ("foreach" 正文第 11 行) 从 "foreach host $hosts { spawn /usr/bin/ssh -q appadm@$host 期望 "appadm@$host:~>" 发送 "su epos\r" 期望 "密码:" 发送 "ep0s05\r" 期望 { "epos..." (file “/appl/ops/web/merger/calendar/survey/eposexp2.sh”第 6 行)
  • @Dren,请阅读stackoverflow.com/help/how-to-ask——很明显,您应该将完整的错误堆栈跟踪放在您的问题中。

标签: shell expect


【解决方案1】:

从错误消息来看,问题似乎是因为未转义的左方括号[。如果你想匹配文字左方括号,那么应该是,

"\\\[appadm@$host ~]" 

原因是,[ 对于TclExpect 都是特殊的。除非转义,否则它将被视为命令调用。

将代码更改为,

expect {
    "epos@$host:/home/appadm>" {send "exit\r"; exp_continue}
    "\\\[appadm@$host ~]" {send "exit\r"}

}

注意:我们不需要转义右方括号。

【讨论】:

  • 我认为只需要一个反斜杠
  • @glennjackman:不,先生。当在双引号中使用时,如果我们只用一个反斜杠作为expect "\[appadm@host ~]" 转义,它将成为一个可以匹配appadm@host ~ 中的任何字符(即'a'或'p'或'd'等)的全局模式。 OP 的问题依赖于匹配文字开放方括号,这就是我使用 3 个反斜杠的原因。
  • @Dinesh 谢谢添加的反斜杠能够接收退出命令。但它似乎在下一个语句中继续,错误如下发送:spawn id exp7 not open while execution "send "exit\r"" ("foreach" body line 16) 从我想要的内部调用是这个语句会让脚本继续 "epos@$host:/home/appadm>" {send "exit\r"; exp_continue} 而此语句在遇到时将在此处结束并继续到下一个主机 "[appadm@$host ~]" {send "exit\r"} 我应该添加;发送“exit\r”后的eof?
  • @Dren :第一次发送exit,会话似乎关闭了。如果观察到 eof,您可以添加 eof 并进一步删除 expectsend
【解决方案2】:

\003的值是controlC^C),很可能是接收端的中断字符。如果expect 按预期发送,它可以很好地停止程序。

回复@Dren 的评论: 如果您发送换行符,更改密码提示可能会拒绝(没有空密码...)并且不会停止您的脚本。

例如

{send "\n\n\n"; exp_continue}

而不是

{send "\003"; exp_continue}

【讨论】:

  • 是的,我专门插入了控件 C,因为我想在询问时跳过更改密码提示并移至下一个主机。除了^C之外,你还有其他方法可以跳过吗?
  • 你的意思是我应该改用下面的 set hosts [split [read $i] "\n"] 而不是 set hosts [split [read -nonewline $i] "\n"] 当我这样做它仍然退出
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 2016-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多