使用expect来实现远程登录ssh

先说说shebang

我们在写一个shell脚本时,总是习惯在最前面加上一行#!/bin/bash,这个就是脚本的shebang,可以把它理解成是一种解释器。至于为什么叫这么个奇怪的名字,C语言和Unix的开发者Dennis Ritchie称它为可能是类似于“hash-bang”的英国风描述性文字;

贴一段wiki上的解释:

在计算机科学中,shebang是一个由井号和叹号构成的字符串行,其出现在文本文件的第一行的前两个字符。 在文件中存在shebang的情况下,类unix操作系统的程序载入器会分析shebang后的内容,将这些内容作为解释器指令,并调用该指令,并将载有shebang的文件路径作为该解释器的参数。

简单的说,它指示了此脚本运行时的解释器,所以,使用文件名直接执行shell脚本时,必须带上这个shebang; 此外,我们还可以在shebang后面直接附加选项,执行时默认使用选项执行;

比如test.shshebang#!/bin/sh -x,那我们执行脚本时:

1
./test.sh hello

相当于:

1
bin/sh -x ./test.sh hello;

而expect编写的脚本,需要用到的shebang为/usr/bin/expect;

需要注意的是:在指定脚本解释器来执行脚本时,shebang会被指定的脚本解释器覆盖,即优先使用指定的脚本解释器来执行脚本(习惯性地用sh ./test.sh却提示command not found

实例脚本

expect的具体语法我这里就不说了,看一下下面的参考资料就好了。其实说来说去,就是根据命令栏上的反馈来输入对应的内容,举一个ssh登陆的例子。如图:
paradin

从这个我们非常熟悉的ssh登陆的过程就看到,在登陆的时候,页面会返回几个交互的问题,而我们就可以针对这几个问题的关键字来输入答案。最后也根据“Welcome”这个关键字认为我们已经登陆成功了,这样就直接在连接的服务器里操作命令。

于是根据这个思路,来写一个远程ssh到A机器上的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/expect -f

set timeout 30 #设定超时时间是30秒,如果是-1那就是永不超时
spawn ssh root@A服务器IP地址 #这里开始ssh连接到目标服务器上

expect {
"*(yes/no)?" { #如果是第一次连接,那么命令栏里就会出现(yes/no)的字样
send "yes\r" #此时匹配yes
expect "*password:" {send "服务器密码\r"} #如果命令栏出现了password的字样,直接填写密码
}
"*password:" {send "服务器密码\r"} #如果不是第一次连接,那么就会直接出现password,所以可以直接填写密码
}
expect "*Welcome*" #连接成功就会出现welcome的字样
send "echo '我就是你的爹地' >> /tmp/123321.txt\r" #此时执行第一个命令
send "df -h\r" #执行第二个命令
send "cp /tmp/123321.txt /tmp/123123.txt\r" #执行第三个命令
interact #脚本fork的子进程会将操作权交给用户,允许用户与当前A服务器的shell进行交互

参考资料

http://blog.sctux.com/?p=343
http://www.zyy1217.com/2017/07/02/linux%20expect%E8%AF%A6%E8%A7%A3/
https://github.com/jiangxianli/SSHAutoLogin
https://peiqiang.net/2014/05/10/ssh-auto-login.html
https://www.jianshu.com/p/9bee08dc3dca

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------