shell脚本解决scp需要输入密码问题

场景:客户要求把96服务器上的数据复制到86服务器上,但是要自动复制,不要人为干预,然后我就登录96服务器,使用ssh命令,登录到86服务器,发现需要输入密码,要想写shell脚本,使用scp命令复制数据的话,需要手动输入密码。

基于此场景,有两个方案。

方案一:96和86服务器配置免密登录

步骤:

1.生成无密码的密钥对

ssh-keygen -t rsa
复制代码

一路回车

2.将公钥添加到本地认证文件中

cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
复制代码

3.设置authorized_keys的访问权限

chmod 600 /root/.ssh/authorized_keys
复制代码

**以上步骤先在每个节点上先执行一遍,然后执行下面操作

4.将每个节点上生成的id_rsa.pub复制到其他所有节点并添加到它们的认证文件中

比如:96上生成的id_rsa.pub,复制到86上

scp /root/.ssh/id_rsa.pub 86:/root/(96上执行)

cat ~/id_rsa.pub >> ~/.ssh/authorized_keys(在86上执行)

scp /root/.ssh/id_rsa.pub 96:/root/(86上执行)

cat ~/id_rsa.pub >> ~/.ssh/authorized_keys(在96上执行)
复制代码

我查看一下,96和86服务器上都有免密到其他服务器的公钥了,如果我再执行ssh-keygen -t rsa命令,会把之前配置的给覆盖。

我查看到目录:.ssh/下有id_rsa.pub。

第2步的目的其实就是id_rsa.pub内容添加到对方机器的authorized_keys,然后我把86服务器上的 id_rsa.pub内容添加到96机器的authorized_keys,就可以了。如果你按照方案一不能解决问题,那么可以使用方案二,我也是使用的方案二,因为免密配置,配置的次数太多了(我的这篇文章blog.csdn.net/Allenzyg/ar…也有免密配置步骤),也想换个方式。哈哈哈~~~

方案二:使用expect

expect就是用来做交互用的,基本任何交互登录的场合都能使用,但是需要安装expect包。

步骤:

1.在96服务器下载expect

yum -y install expect
复制代码

2.配置shell脚本

vim 1.sh
复制代码

填入如下内容:

#!/usr/bin/expect -f

set timeout 30

spawn scp 目录/文件 86:/opt/fanRuan/apache-tomcat-8.5.29/webapps/WebReport/yecai_tctp_income/BL/January/

expect "*password:"

send "123456\r"

expect eof
复制代码

3.执行1.sh文件

注意:expect跟bash类似,使用时要先登录到expect,所以首行要指定使用expect在运行脚本时候要expect  file,不能sh file了,不然会报错:

1.sh: line 4: spawn: command not found

couldn't read file "*password:": no such file or directory

1.sh: line 6: send: command not found

couldn't read file "eof": no such file or directory

说明执行方式不正确,因为expect用的不是bash所以会报错。执行的时候直接./1.sh就可以了

如果执行./1.sh报错:-bash: ./1.sh: Permission denied

解决办法:chmod -R 777 1.sh

首行指定用来执行该脚本的命令程序,这里是/usr/bin/expect

上面语句第一句是设定超时时间为30s,spawn是expect的语句,执行命令前都要加这句

expect "password:"这句意思是交互获取是否返回password:关键字,因为在执行ssh时会返回输入password的提示:root@10.138.98.86's password:

send就是将密码123456发送过去

expect eof 子进程已经结束的eof字符,expect脚本也就退出结束

interact代表执行完留在远程控制台,不加这句执行完后返回本地控制台

知识储备参考:blog.csdn.net/huoyuanshen…