带有帮助的bash脚本中的期待 [英] Help with Expect within a bash script

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

问题描述

我写了一个bash脚本与预期之内,连接到终端服务器和清晰的线条。
我无法弄清楚我得到,在我给所有的括号所必需的错误。我也不理解无法读取文件线:没有这样的文件或目录错误。
请帮助。

我的脚本:

 #!/斌/庆典
VAR = $(预计-c
产卵的telnet 1.1.1.1
预计{
       密码:{发送密码\\ r; exp_continue}
       提示>中{发送恩\\ R; exp_continue}
       密码:{发送密码\\ r; exp_continue}
       提示#{发送CLEA线10 \\ R; exp_continue}
       [确认]{发送Y \\ R; exp_continue}
       提示#{发送CLEA线11 \\ R; exp_continue}
       [确认]{发送Y \\ R; exp_continue}
       提示#{发送退出\\ R}
    }
)回声$ VAR

其输出:

 缺少近距离梅开二度
    在执行
期望
无法读取文件线:没有这样的文件或目录


解决方案

第一个问题是,外壳不跨preT嵌套双引号,你可能会喜欢。解决这个问题的最简单的方法就是把期望程序单引号。因为有在期望程序本身没有单引号,这将是足够的,只要

你会遇到的下一个问题是,有单个期望命令所有的模式和动作会处理它们并行。什么是真正发生的是第一密码:模式将匹配它认为该字符串的任何时间(即即使管理员密码,第二次左右)。这将是一个问题,如果两个密码需要是不同的。至少,相同的模式将需要进入单独的期望命令,以便他们可以按顺序执行。这个问题也影响到你往哪里看它三次,要发送三个不同的响应提示符#模式。

后来,你送的第一个清晰的命令后,你会得到一个错误。预计除$ P $点方括号双引号内的方式,类似于如何壳间preT $()`` (即命令替换)。你会看到类似这样的错误:

 无效的命令名称为确认
    在执行
确认
    从内部调用
预计{

据试图运行确认作为一个Tcl(或期望)命令。你可以使用大括号( {} )以prevent的Tcl把此条间pretation。此外,预计模式被称为水珠EX $默认情况下(即像shell通配符),所以即使你写 {[确认]} 作为模式p $ pssions处理,它仍然不能用于精确的字符串匹配(这将匹配任何单个字符 C 0 N ˚F I - [R M )。您必须使用 -ex 标记来标记精确匹配的模式。

解决这些问题,减少一些不必要的报价,你可能最终的东西是这样的:

 #!/ bin / sh的
VAR = $(预计-c'
  PROC中止{} {
    把超时或EOF \\ n
    1号出口
  }
  产卵的telnet 1.1.1.1
  预计{
    密码:{发密码1 \\ r}
    默认情况下中止
  }
  预计{
    提示> {发送恩\\ R; exp_continue}
    密码:{发密码2 \\ r}
    默认情况下中止
  }
  预计{
    提示#{发送CLEA线10 \\ R; exp_continue}
    -ex {[确认]} {发送Y \\ R}
    默认情况下中止
  }
  预计{
    提示#{发送CLEA线11 \\ R; exp_continue}
    -ex {[确认]} {发送Y \\ R}
    默认情况下中止
  }
  预计{
    提示#{发送退出\\ R; exp_continue}
    超时中断
    EOF
  }
  提出说完OK \\ N
')回声$ VAR

I wrote a bash script with expect within, to connect to a terminal server and clear lines. 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. Kindly help.

My script:

#!/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  

Its output:

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

解决方案

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.

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.

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 {  
⋮

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天全站免登陆