expect实现自动交互由浅入深
expect实现自动交互由浅入深
作为运维人员可以通过Shell可以实现简单的控制流功能,如:循环、判断等。但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如telnet服务器等进行交互的功能。而Expect就使用来实现这种功能的工具。Expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。
安装expect,直接yum install expect -y
expect中相关命令
命令 | 解释 |
---|---|
spawn | 启动新的进程 |
send | 用于向进程发送字符串 |
expect | 从进程接收字符串 |
interact | 允许用户交互 |
exp_continue | 匹配多个字符串在执行动作后加此命令 |
一般步骤:
启动expect进程(spawn)--> 接收进程字符串(expect) --> 匹配字符串,成功发送字符串(send),否则等待 --> 结束
好了就直接步入主题吧,不扯那些没用的。直接上实例:
一. 入门例子:实现自动登录
[root@localhost shell.sh]# vim test.exp
#!/usr/bin/expect
set timeout 30
spawn ssh -l root 192.168.1.106
expect {
"(yes/no)?" { send "yes\r" }
"password:" { send "jiajie\r" }
}
interact
参数 | 解释 |
---|---|
#!/usr/bin/expect | 说明使用的shell环境 |
set timeout 30 | 设置超时时间,单位为秒,-1为没有限制 |
spawn ssh... | 需要执行的命令,这里是ssh登陆命令 |
expect "(yes/no)?" | 判断上次输出结果里是否包含(yes/no)?的字符串 |
send "yes\r" | 执行交互动作,接轨上一个命令,如果上面的expect执行成功,则发送yes |
interact | 执行完成后保持交互状态,把控制权交给控制台 |
执行该实例:./test.exp
如果报错-bash: ./test.exp: Permission denied
,给744权限即可。
二. 使用变量:
[root@localhost shell.sh]# vim test.exp
#!/usr/bin/expect
set ip 192.168.1.106
set user root
set password jiajie
set timeout 30
spawn ssh -l $user $ip
expect {
"(yes/no)?" { send "yes\r";exp_continue }
"password:" { send "$password\r" }
}
interact
set:设置变量,后面直接变量,通过“$变量名”来调用
三. 使用位置参数:
[root@localhost shell.sh]# vim test.exp
#!/usr/bin/expect
if {$argc!=3} {
send_user "Usage:expect need three arguments:ip user password\n"
exit 1
}
set ip [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
set timeout 30
spawn ssh -l $user $ip
expect {
"(yes/no)?" { send "yes\r";exp_continue }
"password:" { send "$password\r" }
}
interact
[lindex $argv num]:表示位置参数,从num=0开始
send_user: 打印当前提示,相当于shell里的echo.
四. 执行多个命令:
[root@localhost shell.sh]# vim test.exp
#!/usr/bin/expect
if {$argc!=3} {
send_user "Usage:expect need three arguments:ip user password\n"
exit 1
}
set ip [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
set timeout 30
spawn ssh -l $user $ip
expect {
"(yes/no)?" { send "yes\r";exp_continue }
"password:" { send "$password\r" }
}
expect "]#" { send "useradd jj\r" }
expect "]#" { send "echo jiajie|passwd --stdin jj\r" }
send "exit\r"
expect eof
exit -onexit {
send_user "useradd jj is successfully.\n"
send_user "Jobs has finished,Goodbye.\n"
}
执行后的结果输出:
[root@localhost shell.sh]# ./test.exp 192.168.1.106 root jiajie
spawn ssh -l root 192.168.1.106
root@192.168.1.106's password:
Last login: Sat Sep 9 03:47:48 2017 from web
[root@localhost ~]# useradd jj
[root@localhost ~]# echo jiajie|passwd --stdin jj
Changing password for user jj.
passwd: all authentication tokens updated successfully.
[root@localhost ~]# exit
logout
Connection to 192.168.1.106 closed.
useradd jj is successfully.
Jobs has finished,Goodbye.
send "exit\r":登录出当前环境。
expect eof:结束expect匹配。
exit -onexit{...}:打印结束的提示信息。
五. shell脚本调用expect(1)
[root@localhost shell.sh]# vim test.sh
#!/bin/bash
ip=$1
user=$2
password=$3
expect <<EOF
set timeout 10
spawn ssh -l $user $ip
expect {
"yes/no" { send "yes\n";exp_continue }
"password" { send "$password\n" }
}
expect "]#" { send "useradd jj\n" }
expect "]#" { send "echo jiajie|passwd --stdin jj\n" }
expect "]#" { send "exit\n" }
expect eof
EOF
执行后的输出结果:
[root@localhost shell.sh]# ./test.sh 192.168.1.106 root jiajie
spawn ssh -l root 192.168.1.106
root@192.168.1.106's password:
Last login: Sat Sep 9 04:10:46 2017 from web
[root@localhost ~]# useradd jj
[root@localhost ~]# echo jiajie|passwd --stdin jj
Changing password for user jj.
passwd: all authentication tokens updated successfully.
[root@localhost ~]# exit
logout
Connection to 192.168.1.106 closed.
[root@localhost shell.sh]#
五. shell脚本调用expect(2)
通过shell脚本通过调用expect脚本实现批量认证:
expect脚本:
[root@localhost shell.sh]# vim scp.exp
#!/usr/bin/expect
if {$argc!=3} {
send_user "Usage:expect need three arguments lisk thks:file host dir\n"
exit 1
}
set srcname [lindex $argv 0]
set hostname [lindex $argv 1]
set destname [lindex $argv 2]
set password "jiajie"
spawn scp $srcname root@$hostname:$destname
set timeout 30
expect {
# -timeout 2
"yes/no" {send "yes\r";exp_continue}
"*password:" {send "$password\r"}
# timeout {puts "expect connect failure,please contact admin.";return}
}
expect eof
exit -onexit {
send_user "Jobs has finished,Goodbye.\n"
}
shell脚本:
[root@localhost shell.sh]# vim scp.sh
#!/bin/bash
if [[ "$#" != "2" ]];then
echo "Usage:$0 src_filename des_filename"
exit 0
fi
IP_LIST=(
192.168.1.106
192.168.1.170
192.168.1.10
)
. /etc/init.d/functions
for ip in ${IP_LIST[*]}
do
expect scp.exp $1 $ip $2 &> /dev/null
if [ $? -eq 0 ];then
action "$ip" /bin/true
else
action "$ip" /bin/false
fi
done
scp.sh脚本通过调用expect脚本来实现分发功能。执行结果如下:
[root@localhost shell.sh]# sh scp.sh /etc/fstab /tmp/
192.168.1.106 [ OK ]
192.168.1.170 [ OK ]
192.168.1.10 [FAILED]
因为并没有192.168.1.10所有报错。
expect实现自动交互由浅入深的更多相关文章
- expect 实现自动交互脚本
1. 说明 在编写脚本时,可能会遇到需要在另一台主机上执行一个命令,或者在本机拷贝另一台主机内的一个文件.如果两台主机之间没有做互信,就会牵扯到用户输入密码的交互过程,这对编写自动脚本来说, 就行不通 ...
- 使用expect实现自动交互,shell命令行自动输入,脚本自动化,变量引用,expect spawn执行带引号命令,expect 变量为空,不生效,不能匹配通配符*,函数,数组
背景 有需求,在允许命令或者脚本跳出交互行,需要进行内容输入,但需要人手动输入,不是很方便,此时可以通过expect来实现自动互动交互. expect是一个自动交互功能的工具,可以满足代替我们实际工作 ...
- 使用expect实现自动交互,shell命令行自动输入
背景 有需求,在允许命令或者脚本跳出交互行,需要进行内容输入,但需要人手动输入,不是很方便,此时可以通过expect来实现自动互动交互. expect是一个自动交互功能的工具,可以满足代替我们实际工作 ...
- Linux--使用expect进行自动交互
在linux下进行一些操作时,有时需要与机器进行一些交互操作,比如切换账号时输入账号密码,传输文件时输入账号密码登陆远程机器等,但有时候这些动作需要在shell脚本中进行,这个时候就可以使用expec ...
- expect简单自动交互-用于密码、命令输入
1. 安装expect #yum -y install expect 2. 新建.exp文件,用于ssh交换机 #vi exp.exp #!/bin/expect set f [open ipfile ...
- 015_使用 expect 工具自动交互密码远程其他主机安装 httpd 软件
#!/bin/bash#删除~/.ssh/known_hosts 后,ssh 远程任何主机都会询问是否确认要连接该主机rm -rf ~/.ssh/known_hostsexpect <<E ...
- 脚本_使用expect自动交互远程主机安装软件
#!bin/bash#功能:使用expect工具自动交互密码,远程到其它主机,安装httpd软件#作者:liusingbon#删除~/.ssh/known-hosts后,ssh远程任何主机,系统都会询 ...
- linux自动交互工具expect,tcl安装和安装包,以及自动互信脚本
linux自动交互工具expect,tcl安装,以及自动互信脚本 工作中需要对几十台服务器做自动互信,无意中发现expect命令,研究一番. 在网上找了许多资料也没有安装成功,摸索着总算成功了.现分享 ...
- SSH批量管理 expect自动交互
SSH批量管理 expect自动交互 原创博文http://www.cnblogs.com/elvi/p/7662908.html # SSH批量管理 # expect自动交互 ########### ...
随机推荐
- Python中str()与repr()函数的区别
在 Python 中要将某一类型的变量或者常量转换为字符串对象通常有两种方法,即str()或者 repr() . >>> a = 10 >>> type(str(a ...
- Java 读书笔记 (五) 目标数据类型转换
数据类型转换必须满足如下规则: 不能对boolean类型进行类型转换 不能把对象类型转换成不相关类的对象 //那不同类的对象可以用同一个名字命名吗?根据作用域原则,可以吧? 把容量大的转换为容量小的 ...
- Elasticsearch笔记三之版本控制和插件
版本控制 1:关系型数据库使用的是悲观锁,数据被读取后就被锁定其他的线程就无法对其进行修改. 2:ex使用的是乐观锁,数据被读取后其他程序还可以对其进行修改,而执行修改时发现此数据已经被修改则修改就会 ...
- 用C++向一个txt文档中写数据
bool CMaked::WriteFileMake(CString filePath, const char *isChange) { ofstream file; //filePath为该txt文 ...
- bzoj 1592 dp
就是dp啊 f[i][j]表示到第i位,最后一位高度是j的最小花费 转移::f[i][j]=minn(f[i-1][k])+abs(a[i]-num[j]);(k<=j) #include< ...
- 【最小生成树】Bzoj1601[Usaco2008 Oct]灌水
Description Farmer John已经决定把水灌到他的n(1<=n<=300)块农田,农田被数字1到n标记.把一块土地进行灌水有两种方法,从其他农田饮水,或者这块土地建造水库. ...
- BZOJ_1345_[Baltic2007]序列问题Sequence_单调栈
BZOJ_1345_[Baltic2007]序列问题Sequence_单调栈 Description 对于一个给定的序列a1,…,an,我们对它进行一个操作reduce(i),该操作将数列中的元素ai ...
- Spring中bean的注入方式
首先,要学习Spring中的Bean的注入方式,就要先了解什么是依赖注入.依赖注入是指:让调用类对某一接口的实现类的实现类的依赖关系由第三方注入,以此来消除调用类对某一接口实现类的依赖. Spring ...
- 【爆料】-《南澳大学毕业证书》UniSA一模一样原件
☞南澳大学毕业证书[微/Q:2544033233◆WeChat:CC6669834]UC毕业证书/联系人Alice[查看点击百度快照查看][留信网学历认证&博士&硕士&海归&a ...
- springboot2.x里面访问静态资源的坑
在spring boot的自定义配置类继承 WebMvcConfigurationSupport 后,发现自动配置的静态资源路径( classpath:/META/resources/,classpa ...