Che*_*evy 8 ssh scripting expect
我正在努力解决在ssh中自动输入密码的经典问题,就像其他人一样,我在黑暗中磕磕绊绊地期待着.最后,我拼凑了一个有点工作的脚本:
#!/usr/bin/expect -f
# command line args
set user_at_host [lrange $argv 0 0]
set password [lrange $argv 1 1]
set timeout 1
# ssh command
spawn ssh -S ~/.ssh/tmp.$user_at_host -M -N -f $user_at_host
# deal with ssh prompts
expect {
"*yes/no*" { send "yes\r" ; exp_continue }
"*assword:" { send "$password\r" ; exp_continue }
}
Run Code Online (Sandbox Code Playgroud)
此脚本仅timeout 1在线路上终止,没有它只是挂起,并且只能通过用户交互(^C)终止.
当该spawn行是一个直接的ssh命令时,脚本立即终止,但这不是你的直接ssh.可能不同的是-f使它在后台运行的选项(但我尝试了没有它的脚本无济于事).
我读过这个interact或者expect eof可能会有所帮助,但我找不到真正能做到的正确的咒语.
我的问题(我认为)是如何制作一个期望脚本,产生一个后台进程,终止没有超时?
编辑:我应该期望(没有双关语意)"使用无密码ssh身份验证"的答案.虽然这是一个合理的建议,但在我的场景中它并不是合适的解决方案:在可信环境中自动测试vanilla已安装的系统,其中不希望/可能向图像添加可信密钥.
你可能想要:
expect {
"*yes/no*" { send "yes\r" ; exp_continue }
"*assword:" { send "${password}\r" }
}
expect $the_prompt
send "exit\r"
expect eof
Run Code Online (Sandbox Code Playgroud)
UPDATE
我错过了你通过ssh发送命令.我想你需要的就是这个:
spawn ssh a@b foo bar baz
expect {
"*yes/no*" { send "yes\r" ; exp_continue }
"*assword:" { send "${password}\r" }
eof
}
Run Code Online (Sandbox Code Playgroud)
你会打eof的时候foo命令完成.
好的,所以我找到了一个似乎有效的排列——
首先,我需要一个wrapper脚本,该脚本将在完成时给出指示:
#!/bin/bash
"$@"
echo "done"
Run Code Online (Sandbox Code Playgroud)
那么expect脚本就变成了:
#!/usr/bin/expect -f
set user_at_host [lrange $argv 0 0]
set password [lrange $argv 1 1]
# no need for timeout 1
set timeout 60
# use the wrapper
spawn wrapper ssh -S ~/.ssh/tmp.$user_at_host -M -N -f $user_at_host
expect {
"*yes/no*" { send "yes\r" ; exp_continue }
"*assword:" { send "$password\r" ; exp_continue }
# use the wrapper
"done" { exit }
}
Run Code Online (Sandbox Code Playgroud)
感谢道格拉斯·利德( Douglas Leeder)(投票赞成)和格伦·杰克曼( glenn jackman)(投票赞成)提供的有用建议。我很乐意不接受这个答案,并接受任何更优雅的答案,也许是一个取消包装脚本的答案。
感谢大家的关注。
| 归档时间: |
|
| 查看次数: |
22212 次 |
| 最近记录: |