在Bash脚本中期望 [英] Expect within a Bash script

查看:119
本文介绍了在Bash脚本中期望的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个带有Expect的Bash脚本,以连接到终端服务器并清除行.

I wrote a Bash script with Expect within, to connect to a terminal server and clear lines.

我无法弄清楚我遇到的错误,因为我已经给出了所有必要的括号.我也不理解couldn't read file "line": no such file or directory错误. 我该如何解决?

I am unable to figure out the error I am getting, as in I have given all the braces necessary. I also do not understanding the couldn't read file "line": no such file or directory error. How can I fix this?

我的脚本:

#!/bin/bash
VAR=$(expect -c "
spawn telnet 1.1.1.1
expect {
       "Password:" { send "password\r" ; exp_continue}
       "Prompt>" { send "en\r" ; exp_continue}
       "Password:" { send "password\r" ; exp_continue}
       "Prompt#" {send "clea line 10\r" ; exp_continue}
       "[confirm]" {send "Y\r" ; exp_continue}
       "Prompt#" {send "clea line 11\r" ; exp_continue}
       "[confirm]" {send "Y\r" ; exp_continue}
       "Prompt#" {send "exit\r" }
    }
")

echo $VAR

其输出:

missing close-brace
    while executing
"expect"
couldn't read file "line": no such file or directory

推荐答案

第一个问题是shell无法按照您的意愿解释嵌套的双引号.解决此问题的最简单方法是将Expect程序放在单引号中.只要Expect程序本身中没有单引号,就足够了.

The first problem is that the shell does not interpret nested double quotes as you might like. The easiest way to fix this is to put the Expect program in single quotes. This will be sufficient as long as there are no single quotes in the Expect program itself.

您将遇到的下一个问题是,在单个expect命令中包含所有模式和操作将并行处理它们.实际上发生的情况是,第一个Password:模式将在它看到该字符串的任何时间匹配(即第二次即使是管理员密码).如果两个密码需要不同,这将是一个问题.至少,相同的模式将需要进入单独的expect命令,以便可以顺序执行它们.此问题还会影响Prompt#模式,在该模式中您需要查找三次并希望发送三个不同的响应.

The next problem you will run into is that having all the patterns and actions in a single expect command will process them in parallel. What is actually happens is that the first Password: pattern will match any time it sees that string (i.e. even for the admin password the second time around). This will be a problem if the two passwords need to be different. At a minimum, identical patterns will need to go into separate expect commands so that they can be executed sequentially. This problem also affects the Prompt# pattern where you look for it three times and want to send three different responses.

稍后,在发送第一个清除命令后,您将得到一个错误. Expect解释双引号内的方括号的方式类似于shell解释$()``的方式(即命令替换).您会看到这样的错误:

Later, you will get an error after you send the first clear command. Expect interprets square brackets inside double quotes in a way that is similar to how shells interpret $() or `` (i.e. command substitution). You will see an error like this:

invalid command name "confirm"
    while executing
"confirm"
    invoked from within
"expect {  
⋮

它正在尝试作为Tcl(或Expect)命令运行confirm.您可以使用大括号({})防止Tcl进行此解释.此外,默认情况下,期望模式被视为全局"表达式(例如,类似于外壳通配符),因此,即使您将{[confirm]}编写为模式,也不会将其用于精确的字符串匹配(它将与任何单个字符匹配) confirm).您必须使用-ex标志将模式标记为完全匹配.

It is trying to run confirm as a Tcl (or Expect) command. You can use curly brackets ({}) to prevent Tcl from making this interpretation. Furthermore, expect patterns are treated as "glob" expressions by default (i.e. like shell wildcards), so even if you write {[confirm]} as the pattern, it will still not be used for an exact string match (it would match any single character c, o, n, f, i, r, or m). You must use the -ex flag to mark the pattern for exact matching.

解决这些问题,删除一些不必要的引号,您可能最终会得到这样的结果:

Fix these issues, drop some of the unnecessary quoting, and you might end up with something like this:

#!/bin/sh
VAR=$(expect -c '
  proc abort {} {
    puts "Timeout or EOF\n"
    exit 1
  }
  spawn telnet 1.1.1.1
  expect {
    Password:        { send "password1\r" }
    default          abort
  }
  expect {
    Prompt>          { send "en\r"; exp_continue }
    Password:        { send "password2\r" }
    default          abort
  }
  expect {
    Prompt#          { send "clea line 10\r"; exp_continue }
    -ex {[confirm]}  { send "Y\r" }
    default          abort
  }
  expect {
    Prompt#          { send "clea line 11\r"; exp_continue }
    -ex {[confirm]}  { send "Y\r" }
    default          abort
  }
  expect {
    Prompt#          { send "exit\r"; exp_continue }
    timeout          abort
    eof
  }
  puts "Finished OK\n"
')

echo "$VAR"

这篇关于在Bash脚本中期望的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆