bash - Expect脚本如何确定expect_out的内容
问题描述
我正在尝试编写一个脚本,它将向 vpn 提供凭据,但需要注意的是 VPN 要求我提供 OTP。
这是我的脚本:
#! /usr/bin/expect
set vpn [ lindex $argv 0]
set group [ lindex $argv 1]
set user [ lindex $argv 2]
set secret [ lindex $argv 3]
log_user 2
spawn nmcli con up $vpn --ask
expect {
"GROUP:" {
send "$group\r"
exp_continue
}
"Username:" {
send "$user\r"
exp_continue
}
Password: {
send_user "\nProvide RSA OTP:"
expect_user -re ":(.*)\r"
set otp $expect_out(0,string) <--------- Error!!!
set pass "$secret$otp"
send "$pass\r"
exp_continue
}
"Connection successfully activated" {
send_user "Connected to VPN\r"
}
"Login failed" {
send_user "Login failed\r"
exp_continue
}
"already active" {
send_user "Already connected to VPN\r"
}
}
exit
我在我认为是问题根源的地方添加了一个箭头,因为当我运行这个脚本时,它看起来像 expect_out contains Password:
。鉴于我在手册页中读到的内容,我想每次进行新匹配时都会清除缓冲区,因此它包含在最近的期望子句中匹配的字符串(在这种情况下expect_user -re ":(.*)\r"
),但似乎我错了。我没有看到任何说明需要使用不同的功能访问 expect_user 内容的注释interact
,所以我不确定我的密码去哪儿了?
谢谢
解决方案
使用时,send_user
您不会看到所写内容的回显,这与发送到生成的命令时不同,因此:
除非用户明确键入,否则您将永远不会匹配。此外,您将阅读换行符,而不是回车符。所以使用
expect_user -re "(.*)\n"
获取用户输入并且$expect_out(1,string)
(1 not 0) 将包含输入。
您所观察到的是 中的超时expect_user
,这就是变量未更新且仍包含旧匹配项的原因。
为了保护自己免受看不见的超时,您可以设置一个“全局”超时检查,从
proc abort { } { send_user "Timeout!" ; exit 2 }
expect_before timeout abort
似乎在eachexpect_before
之前完成expect
,而且在 each 之前完成。expect_user
推荐阅读
- java - 如何在android中每5秒在后台无限运行特定方法?
- django - Django没有设置相同的站点cookie
- python-3.x - 如果我有细胞的坐标,如何找到 voronoi 细胞的种子?
- java - 未知错误:未处理的检查器错误:{"code":-32000,"message":"Cannot take screenshot with 0 width."}
- python - 机器人消息删除反应
- ruby-on-rails - 如何将sidekiq作业延迟10分钟,最后计算它们?
- python - Python:递归函数的奇怪结果
- python - 如何更改代码中的 for 循环以在我的数据框中为我提供额外的列?
- java - Java spring boot JPA DLL-auto:有选择地更新
- spring - spring-cloud-starter-sleuth + axon-tracing-spring-boot-starter =?