我写了一个期望内部的bash脚本,连接到终端服务器和清除行.我无法弄清楚我得到的错误,因为我已经给了所有必要的括号.我也不理解couldn't read file "line": no such file or directory错误.请帮助.
我的剧本:
#!/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
Run Code Online (Sandbox Code Playgroud)
它的输出:
missing close-brace
while executing
"expect"
couldn't read file "line": no such file or directory
Run Code Online (Sandbox Code Playgroud)
Chr*_*sen 20
第一个问题是shell不会像你想的那样解释嵌套的双引号.解决此问题的最简单方法是将Expect程序放在单引号中.只要Expect程序本身没有单引号,这就足够了.
您将遇到的下一个问题是,在单个expect命令中拥有所有模式和操作将并行处理它们.实际发生的是第一个Password:模式将在它看到该字符串的任何时间匹配(即使第二次使用管理员密码).如果两个密码需要不同,这将是一个问题.至少,相同的模式需要进入单独的expect命令,以便它们可以顺序执行.此问题还会影响Prompt#您查找三次并希望发送三种不同响应的模式.
稍后,在发送第一个clear命令后,您将收到错误消息.Expect以类似于shell解释$()或``(即命令替换)的方式解释双引号内的方括号.你会看到这样的错误:
invalid command name "confirm"
while executing
"confirm"
invoked from within
"expect {
?
Run Code Online (Sandbox Code Playgroud)
它试图confirm作为Tcl(或Expect)命令运行.您可以使用花括号({})来阻止Tcl进行此解释.此外,预计模式被视为默认"来代替"表达式(即像贝壳通配符),所以即使你写{[confirm]}的模式,它仍然不能用于精确的字符串匹配(它会匹配任何单个字符c,o,n,f,i,r,或m).您必须使用该-ex标志来标记模式以进行精确匹配.
解决这些问题,删除一些不必要的引用,你可能最终得到这样的东西:
#!/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"
Run Code Online (Sandbox Code Playgroud)