linux中用expect处理脚本中的手工交互
在脚本处理自动化的操作中,有些操作是需要交互的,就是问问题,然后回答,
比如ssh登录某台未登录过的机器,会提示这台机器的指纹不认识,问你是否继续?如果回答继续的话,又问你密码是多少?
就像这样,第一个问题:
The authenticity of host 'igs (10.0.x.5x)' can't be established.
ECDSA key fingerprint is SHA256:DHJAqjIfLNmsz8146I/QyXbfGoFhtJHvp7e0Gbh988A.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
第二个问题:
Warning: Permanently added 'igs,10.0.x.5x' (ECDSA) to the list of known hosts.
Authorized users only. All activities may be monitored and reported.
root@igs's password:
想这样的交互,如果也不要手工介入的话,就可以使用expect来做。
介绍如下:
Expect is a program that “talks” to other interactive programs according to a script. Following the script, Expect knows what can be expected from a program
and what the correct response should be
.
An interpreted language provides branching and high-level control structures to direct the dialogue. In addition, the user can take control and interact directly when desired, afterward returning control to the script.
总之是可以识别预期,可以给出应答,并且可以做逻辑处理,还可以手自一体~
Expect uses Tcl (Tool Command Language). Tcl provides control flow (e.g., if, for, break), expression evaluation and several other features such as recursion, procedure definition, etc.
很关键的一点,是对于输出问题的预期,这个涉及到样式匹配(pattern match)。因为样式里面,如果含有了特殊字符,是需要特别注意的,所以我们尽量避免这种情况,比如这里样式用的 continue connecting
。样式匹配并不需要匹配整个的输出字符串,只有匹配到任意位置就可以了,具体可以参考expect手册的expect 命令部分。
每次有新的输出,都会把expect{}里的样式依顺序匹配一遍。
exp_continue: allows expect itself to continue executing rather than returning as it normally would. 这一点好像很重要,对于执行完就返回,而不是执行后进入交互界面的进程来说。
interact是将当前进程的控制器返还给用户,这里就是ssh进程,所以我们进入到了ssh登录成功后的交互界面。如果当前进程已经结束的话,那么interact会报错。
[root@ecs-d589 ~]# cat e1.sh
#!/usr/bin/expect -f
set timeout 5
set VAR [lindex $argv 1]
spawn ssh root@$argv
expect {
"continue connecting" {send "yes\r"; exp_continue}
"password:" {send "Xsw_mypass\r"};
}
interact
运行效果如下:
[root@ecs-d589 ~]# ./e1.sh igs
spawn ssh root@igs
The authenticity of host 'igs (10.0.0.53)' can't be established.
ECDSA key fingerprint is SHA256:DHJAqjIfLNmsz8146I/QyXbfGoFhtJHvp7e0Gbh93lA.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'igs,10.0.0.53' (ECDSA) to the list of known hosts.
Authorized users only. All activities may be monitored and reported.
root@igs's password:
Welcome to Huawei Cloud Service
Last failed login: Mon Jul 4 11:32:07 CST 2022 from 10.0.0.27 on ssh:notty
There was 1 failed login attempt since the last successful login.
Last login: Sun Jul 3 21:30:10 2022 from 10.0.0.27
Welcome to 4.19.90-2003.4.0.0036.oe1.aarch64
System information as of time: Mon Jul 4 11:49:25 CST 2022
System load: 0.00
Processes: 111
Memory used: 10.2%
Swap used: 0.0%
Usage On: 3%
IP address: 10.0.0.53
Users online: 1
[root@ecs-euler-gauss ~]#
这里文件命名为了.sh,其实它是一个expect脚本。
最后再放一个expect脚本,自动的将公钥传到指定IP的服务器上,这样以后可以和服务器自动交互。
#!/bin/bash
ipfile=$1
echo "input file is "${ipfile}
for ip in `cat ${ipfile}`
do
echo ${ip}
expect <<EOF
set timeout 5
spawn ssh-copy-id ${ip}
expect {
"continue connecting" { send "yes\r"; exp_continue }
"password:" { send "thepasswordofserver\r"; exp_continue };
}
EOF
done
执行后如下:
[root@ecs-d589 ~]# ./push_pub.sh my_ip
input file is my_ip
10.0.0.53
spawn ssh-copy-id 10.0.0.53
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '10.0.0.53 (10.0.0.53)' can't be established.
ECDSA key fingerprint is SHA256:DHJAqjIfLNmsz8146I/QyXbfGoFhtJHvp7e0Gbh93lA.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Authorized users only. All activities may be monitored and reported.
root@10.0.0.53's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '10.0.0.53'"
and check to make sure that only the key(s) you wanted were added.
通过验证,ssh可以自动使用密钥对登录了。
- 点赞
- 收藏
- 关注作者
评论(0)