使用 expect 命令实现自动登录的脚本,网上有很多,可是没有一个清晰易懂,初学者大都是照抄、收藏,可是为什么要这么写却不知其然。

米扑博客用一个最短的例子说明脚本的原理。 

脚本代码如下: 

#!/usr/bin/expect 
set timeout 30 
spawn ssh -l username 192.168.1.1 
expect "password:" 
send "ispass\r" 
interact 

 

1. [#!/usr/bin/expect] 

第一行告诉操作系统,脚本里的代码使用那一个shell来执行。

这里的expect其实和linux下的bash、windows下的cmd是一类东西。 

注意:这一行需要在脚本的第一行,注释符井号#开头

 

2. [set timeout 30] 

设置超时时间,计时单位是:秒 

设置整个脚本的执行超时时间为 30秒

 

3. [spawn ssh -l username 192.168.1.1] 

spawn是进入expect环境后才可以执行的expect内部命令,如果没有装expect或者直接在默认的SHELL下执行是找不到spawn命令的。

所以不要用 “which spawn“之类的命令去找spawn命令。好比windows里的dir就是一个内部命令,这个命令由shell自带,你无法找到一个dir.com 或 dir.exe 的可执行文件。 

它主要的功能是给ssh运行进程加个壳,用来传递交互指令。 

 

4. [expect "password:"] 

这里的expect也是expect的一个内部命令,expect的shell命令和内部命令是一样的,但不是一个功能,习惯就好了。

这个命令的意思是判断上次输出结果里是否包含“password:”的字符串,如果有则立即返回,否则就等待一段时间后返回,这里等待时长就是前面设置的30秒 

 

5. [send "ispass\r"] 

这里就是执行交互动作,与手工输入密码的动作等效。 

温馨提示: 命令字符串结尾别忘记加上“\r”,如果出现异常等待的状态可以核查一下。 

 

6. [interact] 

执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。

如果没有这一句登录完成后会退出,而不是留在远程终端上。如果你只是登录过去执行 

#!/usr/bin/expect 
# Change a login shell to bash 
set user [lindex $argv 0] 
spawn bash $user 
expect "]:" 
send "/bin/bash " 
expect eof 
exit

 

ssh或登陆linux主机不需要输入密码的几种方法 

一、 本地登陆不用密码

passwd  -d  USER  // 删除用户密码,使其登陆无需密码,直接登陆,恢复需重新设定密码即可

补充:

   passwd  -l  USER  // 锁定用户,不让其登陆。

   passwd  -u  USER  // 解除锁定,让其登陆。

 

二、 ssh登陆不用密码

用SSH登录远程主机,每次都输入密码挺麻烦的,其实可以用密钥文件来登录:

1. 用ssh-keygen命令生成private/public密钥对,提示问题都用默认回答即可。

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/mimvp/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/mimvp/.ssh/id_rsa.
Your public key has been saved in /home/mimvp/.ssh/id_rsa.pub.

 

2. 用ssh-copy-id命令把公钥复制到远程主机上,user就是你登录用的用户名

$ ssh-copy-id -i /root/.ssh/id_rsa user@remote_host

 

3. 验证一下吧

$ ssh user@remote_host echo "it works"

 

三、Expect的应用---scp/ssh登陆

例如:

三服务器A.B.C 假设A.C要互相访问需经过B,本实现A与C之间的互访。

A - B - C

A.B.C密码分别为:PWDA、PWDB、PWDC。操作主机为A。

 

1. 从A到C的自动SSH登陆

#!/usr/bin/expect -f
set timeout 30
spawn ssh root@B
expect "password:"
send "PWDB\r"
expect "]*"
send "ssh root@C\r"
expect "password:"
send "PWDC"
interact

 

2. 从A到C文件的SCP

#!/usr/bin/expect -f
set timeout 300
set file [lindex $argv 0]
spawn scp $file root@B:/root/
expect "password:"
send "PWDB\r"
expect "]*"
spawn ssh root@B
expect "password:"
send "PWDB\r"
expect "]*"
send "scp $file root@C:/root/\r"
expect "password:"
send "PWDC\r"
expect "]*"
exit
interact

 

3. 从C到A文件的SCP

#!/usr/bin/expect -f
set timeout 300
set file [lindex $argv 0]
spawn ssh root@B
expect "password:"
send "PWDB\r"
expect "]*"
send "scp root@C:/root/$file ./\r"
expect "password:"
send "PWDC\r"
expect "]*"
send "exit\r"
expect "]*"
spawn scp root@B:/root/$file ./
expect "password:"
send "PWDB\r"
interact

 

 

参考推荐

Linux shell脚本通过expect实现自动输入密码

Linux两台主机之间建立信任

Linux 修改SSH 默认端口 22,防止被破解密码

Linux 修改默认端口、增加普通用户、使用密钥等安全登录SSH

Linux ssh 切换登录用户自动转到root用户

Linux expect 命令无需输入密码登陆

Linux sudo 免密码输入

SecureCRT 自动登录设置

JumpServer 堡垒机环境搭建详解

Windows 连接 Linux 常用工具

Linux之/etc/profile、~/.bash_profile等几个文件的执行过程

自建服务器解决外网访问内网的端口穿透映射

LastPass 跨平台密码管理工具