昨天突然发现了ssh 后面直接跟命令的使用方法,想到以前用expect实现自动交互时出现的问题,会不会是该问题导致的呢?结果修改了下脚本,还真把问题解决了,无知真可怕呀,@@;今天就再花点功夫分析总结下,也算是对expect 实现自动交互的一个总结吧!

下面分析下用expect实现ssh配公钥并实现scp不需要密码登陆的一个脚本:

1 #!/usr/bin/expect -f                  -f参数指明读取命令的位置
2
3 spawn echo "######running to generate a ssh-public-key######"
4 spawn ssh-keygen -t rsa 执行命令生成公钥
5 expect " Enter file in which to save the key (/root/.ssh/id_rsa):" 保存目录选择默认;
6 send "\r"
7 expect { 这里出现一个分支选择结构,一个是覆盖原来的公钥,一个是直接生成(原来没有公钥)
8 "Overwrite (y/n)" {send "y\r" ;exp_continue } 覆盖原来的公钥(比直接生成多一个选择)

10 "Enter passphrase (empty for no passphrase):"{send "123456\r"} 输入口令,可选择回车
11 }
12 expect "Enter same passphrase again:" 再次输入
13 send "123456\r\n"
14 set timeout 5
15 expect -re "\](\$|#) " 完成后返回到提示符下
16 spawn scp /root/.ssh/id_rsa.pub @172.16.3.63:/root 上传生成的公钥到服务器

23 set timeout 20
24 expect "password:"
25 send "loongson\r" 输入密码

29 expect -re "\](\$|#) " 完成后返回到提示符下
30 spawn ssh root@172.16.3.63 cat /root/id_rsa.pub >>/root/.ssh/authorized_keys 实现ssh远程登录,并完成一条命令操作(公钥写入到授权文件)
31 expect {
32 "yes/no" {send "yes\r" ;exp_continue } 连接确认
33 "password:" { send "loongson\r" } 远程服务端密码
34 }

39
40 expect eof
41 exit

输出:

1覆盖的情况:

Loong:~/ssh_test# ./new.sh 
spawn echo ######running to generate a ssh-public-key######
spawn ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
/root/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again: spawn scp /root/.ssh/id_rsa.pub @172.16.3.63:/root
root@172.16.3.63's password:
id_rsa.pub 100% 392 0.4KB/s 00:00
spawn ssh root@172.16.3.63 cat /root/id_rsa.pub >>/root/.ssh/authorized_keys
root@172.16.3.63's password:
Loong:~/ssh_test#

2 直接生成

待续!


二、测试过程中遇到的问题:

spawn scp /root/.ssh/id_rsa.pub @172.16.3.63:/root             上传生成的公钥到服务器

下面的expect 忽略了一种情况,就是第一次连接该机器的时候会出现询问是否连接:Are you sure you want to continue connecting (yes/no)?

所以要增加一种选择的情况;

/root/.ssh/id_rsa.pub: No such file or directory     手动删除本地的id_rsa.pub 文件后再运行到scp那步会报该错误,且查看文件的话并没有生成id_rsa.pub文件;如果选择覆盖的话则不会出现该错误,有待分析。


 22 #expect -re "\](\$|#) "
 23 #send "ls\r"  24 #send "ssh 172.16.1.63"   添加该3行会导致一个报错,不清楚为啥。