Linux 在expect脚本中使用if/else
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18648559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using if/else in expect script
提问by theillien
I recently updated and reformatted my /etc/hosts file and would like to run through every system (roughly 1000) to refresh my known_hosts file. I'm looking at using an expect script to send "yes" to the RSA fingerprint question. Simple enough. However, I know some of these systems are completely new to me and my password has not been set. This creates two possibilities:
我最近更新并重新格式化了我的 /etc/hosts 文件,并希望通过每个系统(大约 1000 个)来刷新我的 known_hosts 文件。我正在考虑使用期望脚本向 RSA 指纹问题发送“是”。足够简单。但是,我知道其中一些系统对我来说是全新的,而且我的密码还没有设置。这就产生了两种可能性:
"yes" is sent to the RSA fingerprint question and I'm logged into the server. I'll then need to send an exit to close the connection before moving onto the next host. Or...
"yes" is sent to the RSA fingerprint question and I'm presented with the prompts to update my password starting with the current and followed by the new password entered twice. The connection will automatically close after the password is updated moving onto the next host.
“是”被发送到 RSA 指纹问题,我登录到服务器。然后,在移动到下一个主机之前,我需要发送一个退出来关闭连接。或者...
“是”被发送到 RSA 指纹问题,我会收到提示以更新我的密码,从当前密码开始,然后是两次输入的新密码。更新密码后,连接将自动关闭,移动到下一台主机。
I think I have a basic grasp of the concept of "if/else" in expect, but I don't fully understand how to nest them, if there is a better way, or if I'm completely off-base to begin with.
我想我对期望中的“if/else”概念有了基本的了解,但我不完全理解如何嵌套它们,是否有更好的方法,或者我是否完全偏离基础.
This is what I have right now:
这就是我现在所拥有的:
set file1 [open [lindex $argv 0] r]
set pw1 [exec cat /home/user/.pw1.txt]
set pw2 [exec cat /home/user/.pw2.txt]
while {[gets $file1 host] != -1} {
puts $host
spawn -noecho "ssh $host"
expect {
"continue connecting"{
send "yes\r"
expect {
"current" {
send $pw2\r
} "New password" {
send $pw1\r
} "Retype new password" {
send $pw1\r
}
}
expect "msnyder"
send "exit\r"
}
interact
}
The file1 variable is the list of hosts to run the script against.
file1 变量是运行脚本的主机列表。
I know it isn't accurate because it errors on line 22. But, I have no idea what needs to be fixed.
我知道它不准确,因为它在第 22 行出错。但是,我不知道需要修复什么。
采纳答案by glenn Hymanman
Two errors I spotted:
我发现了两个错误:
- missing close brace, probably for the "continue connecting" block
- missing space before the open brace of "continue connecting". Tcl (hence Expect) is very sensitive to whitespace as it is parsed into wordsbefore the commands are evaluated. For the very few gory details, see the 12 syntax rules of Tcl.
Your code might look like:
您的代码可能如下所示:
while {[gets $file1 host] != -1} {
puts $host
spawn -noecho "ssh $host"
expect {
"continue connecting" {
send "yes\r"
expect {
"current" {
send -- $pw2\r
exp_continue
}
"New password" {
send -- $pw1\r
exp_continue
}
"Retype new password" {
send -- $pw1\r
exp_continue
}
msnyder
}
send "exit\r"
}
}
interact
}
Notes:
笔记:
exp_continue
is used to "loop" back up to theexpect
statement: in this case, you will expect to see all of "current", "new" and "retype", so you don't want to bail out until you see your prompt.- get into the habit of typing
send -- something
. Without the double dash, you'll be surprised the day someone types in a password with a leading dash.
exp_continue
用于“循环”回到expect
语句:在这种情况下,您将期望看到所有“当前”、“新”和“重新输入”,因此在看到提示之前您不想退出。- 养成打字的习惯
send -- something
。如果没有双破折号,当有人输入带前导破折号的密码时,您会感到惊讶。
回答by georgey
You can probably avoid having the script run like a human and just spawn an expected to fail ssh connection which will automatically accept the host RSA key and not bother with prompting for a password; you can do that later for new systems where you need to initiate a password.
您可能可以避免让脚本像人类一样运行,而只是生成一个预期会失败的 ssh 连接,该连接将自动接受主机 RSA 密钥,而不必费心提示输入密码;您可以稍后为需要启动密码的新系统执行此操作。
Temporarily try adding this to your ~/.ssh/config file until your script is finished:
暂时尝试将其添加到您的 ~/.ssh/config 文件中,直到您的脚本完成:
Host *
Protocol 2
PasswordAuthentication 0
StrictHostKeyChecking 'no'
CheckHostIP 'no'
UserKnownHostsFile ~/.ssh/known_hosts_new
Then when the new know_hosts_new file is loaded up, you can replace the default ~/.ssh/known_hosts and remove the UserKnownHostsFile line from your config.
然后当新的 know_hosts_new 文件被加载时,你可以替换默认的 ~/.ssh/known_hosts 并从你的配置中删除 UserKnownHostsFile 行。