Linux expect 实现自动人机交互 | 跨计算机scp/
1.背景简介
shell脚本在处理自动循环或大的任务方面可节省大量的时间,通过创建一个处理任务的命令清单,使用变量、条件、算术和循环等方法快速创建脚本以完成相应工作,这比在命令行下一个个敲入命令要省时省力得多。
但是有时候我们可能会需要实现和交互程序如ftp, telnet服务器等进行交互的功能,需要我们去输入密码等进行人机交互,如果任务量非常大时,需要反复的检测和手动输入密码,就会很麻烦,这时候我们需要用到shell的自动交互功能。
这里我们以跨计算机进行大量文件备份为例子,介绍软件expect的使用。
2.expect的介绍和使用
expect是一个免费的编程工具,用来实现自动的交互式任务,且无需人为干预。expect非常的简单小巧,在自动化部署等诸多项目上面非常好用。
expect的详细安装和介绍可以参照官网或者如下链接,介绍得比较详细:https://blog.csdn.net/wangtaoking1/article/details/78268574
用whereis expect
去判断你的计算机有没有安装expect
这里只进行几个核心命令的强调和实际示例问题的解决。
![](https://img.haomeiwen.com/i25787609/b8c5bffc0728daeb.png)
expect
命令通常用来等待一个进程的反馈,我们根据进程的反馈,再发送对应的交互命令。它会根据你提供的pattern等你运行的程序反馈,当遇到你执行的程序或命令输出了指定的pattern,expect就会识别到。(识别)
send
命令接收一个字符串参数(你指定的,例如你的用户名或密码),并将该参数发送到进程。这个就是在expect识别了后,然后自动将内容输入给你的程序和命令。(自动交互)
spawn
命令用来启动新的进程(命令/程序),spawn后的send和expect命令都是和使用spawn打开的进程进行交互。(核心任务)
interact
命令用的其实不是很多,一般情况下使用spawn、send和expect命令就可以很好的完成我们的任务;但在一些特殊场合下还是需要使用interact命令的,interact命令主要用于退出自动化,进入人工交互。如果你执行程序不需要最后个性化去指定,那就不要它,运行完停止就好。(指定交互)
3.实际使用
下面以将本算机的文件传输到别的计算机上进行文件备份为例子。
大文件常用的传输方式有scp
, rsync
等,不了解的话可以事先简单去了解一下,反正可以理解成就是cp
复制命令的高阶、高速、稳定版。
补充rsync的基本用法:主要就三种方式
#在同一台计算机上进行从source路径到destination路径
rsync [OPTION] SRC DEST
#将本机文件传输到另一台,USR用户名,HOST是ssh地址
rsync [OPTION] SRC [USER@]HOST:DEST
#将另一台计算机文件传输到本机上,USR用户名,HOST是ssh地址
rsync [OPTION] [USER@]HOST:SRC DEST
#第四种和第三种是相对的,同样第五种和第二种是相对的,它们各自之间的区别在于登陆认证时使用的验证方式不同。
rsync [OPTION] [USER@]HOST::SRC DEST
rsync [OPTION] SRC [USER@]HOST::DEST
至于options就基本的几个,记住最常用的几个即可,比如 -a、-r、-v、-z、--delete 和 --exclude等。详见:http://c.biancheng.net/view/6121.html
跨计算机运行的最大障碍在于密码的输入,每一次进行访问都会需要人为地输入登录密码。当然,rsync支持免密码传输,那前提是你输入的计算机ssh设置为免密码登录。但是,对于生产的计算器,或者服务器,而非私人的,这个免密操作是不被允许的。
所以我们结合expect的自动交互和rsync命令实现:(麻烦的是需要先写一个expect的程序,然后循环去调用它)
expect程序:rsync.exp
#!/usr/bin/expect
set timeout 1080
set file [lindex $argv 0]
set password 123456
spawn rsync -avrp $file 10.0.015:/pakpobox/pobox7d2/atac1-130
expect "*password*" {send "$password\r"}
expect eof
#!/usr/bin/expect
为expect的编译器,就是whereis expect
的返回路径
set timeout 1080
为expect的等待时间,这里是18min。这个特性是防止那些执行死机的命令的。一旦到了这个timeout,还是没有屏幕输出的话(这里是spwan后面命令的输出),expect脚本就会开始执行下面其他的代码了。或者我们在expect脚本中如果定义了timeout的响应代码的话,这些代码就会被执行。单位是秒,默认是10秒,可以给定具体时间,给定-1就是无timeout,永不执行下面的代码,知道它期待的pattern出现为止。
spawn
后面就是程序或命令,它一个spawn只识别一个程序,所以不能直接管道符,我们才需要额外去循环调用。
expect
后面就是要识别的pattern,send
就是自动传入的内容。
expect eof
结束标识,运行到此结束,可以用前面说的interact
进行交互作为结束。
其他为变量设置set 变量名 内容
, 且exp不识别#注释符。
自动执行的脚本:rsync.sh
#!/bin/bash
filelist=`cat sample1.txt` #filelist获取
for i in $filelist
do expect ./rsync.exp $i
done
推荐后台执行,就可以彻底set free了现在。
nohup bash rsync.sh &