ICE.ICE|

韩憨

园龄:4年7个月粉丝:42关注:47

centos7 自动交互expect 安装使用

原文链接:https://blog.csdn.net/qq_41944882/article/details/105956317

一、概述
通过Shell可以实现简单的控制流功能,如:循环、判断等。但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如telnet服务器等进行交互的功能。而Expect就使用来实现这种功能的工具。
Expect是一个免费的编程工具语言,用来实现自动与交互式任务进行通信,而无需人工干预。Expect是一个用来实现自动交互功能的软件套件 。系统管理员可以用它来创建脚本以实现对命令或程序提供输入,而这些命令和程序是期望从终端(terminal)输入的,一般来说这些输入都需要手工输入。 Expect则可以根据程序的提示模拟标准输入提供给程序需要的输入来实现交互程序执行。甚至可以实现实现简单的BBS聊天机器人。Expect是不断发展的,随着时间的流逝,其功能越来越强大,已经成为系统管理员的的一个强大助手。Expect需要Tcl编程语言的支持,要在系统上运行Expect必须首先安装Tcl。

二、Expect工作原理
从最简单的层次来说,Expect的工作方式象一个通用化的Chat脚本工具。Chat脚本最早用于UUCP网络内,以用来实现计算机之间需要建立连接时进行特定的登录会话的自动化。
Chat脚本由一系列expect-send对组成:expect等待输出中输出特定的字符,通常是一个提示符,然后发送特定的响应。例如下面的 Chat脚本实现等待标准输出出现Login:字符串,然后发送somebody作为用户名;然后等待Password:提示符,并发出响应 sillyme。
引用:login: somebody pssword: sillyme
这个脚本用来实现一个登录过程,并用特定的用户名和密码实现登录,Expect最简单的脚本操作模式本质上和Chat脚本工作模式是一样的。

三、安装expect
1.yum源安装expect,使用yum源可以自动解决依赖

[root@test1 man]# yum -y install expect

2.源码包方式安装expect
(1)安装tcl软件包,因为expect依赖于tcl,所以得先解决依赖问题
这里安装8.4.19版本

[root@test1 mnt]# wget https://sourceforge.net/projects/tcl/files/Tcl/8.4.19/tcl8.4.19-src.tar.gz

解压缩并安装tcl

[root@test1 mnt]# tar -zxvf tcl8.4.19-src.tar.gz
[root@test1 mnt]# cd tcl8.4.19/unix && ./configure --prefix=/usr/tcl && make && make install

(2)下载expect并安装
这里下载expect5.45

[root@test1 mnt]# wget http://sourceforge.net/projects/expect/files/Expect/5.45/expect5.45.tar.gz

解压缩并安装exxpect

[root@test1 mnt]# tar -zxvf expect5.45.tar.gz
[root@test1 mnt]# cd expect5.45/ && ./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-tclinclude=../tcl8.4.19/generic && make && make install
[root@test1 expect5.45]# ln -s /usr/tcl/bin/expect /usr/bin/expect

四、expect的语法
语法:expect [选项] [ -c cmds] [ [ -[f|b] ] cmdfile] [ args]
选项:-c:从命令行执行expect脚本,默认expect是交互地执行的 -d:可以输出输出调试信息

expect中相关命令:

spawn:启动新的进程
send:用于向进程发送字符串
expect:从进程接收字符串
interact:允许用户交互
exp_continue:匹配多个字符串在执行动作后加此命令
expect:最常用的语法(tcl语言:模式-动作)
set timeout 30:设置超时时间timeout为30s,expect命令阻塞超时时会自动往下继续执行。将timeout配置为-1时表示expect一直阻塞直到与期待的字符串匹配上才继续往下执行。超时时间timeout默认为10s。
[lindex $argv n]:可以在脚本中使用该命令获取在脚本执行时传入的第n个参数。这里argv为传入的参数,另外argv为传入的参数,另外argc表示传入参数的个数,$argv0表示脚本名字。另外我们也可以使用[lrange $argv sn en]命令获取第sn到第en个参数。

实用代码分析
通过一些常用的expect脚本来具体的说明如何使用expect来完成日常的一些工作

#!/usr/bin/expect //使用expect来解释该脚本
set timeout 30 //设置超时时间,单位为秒,默认情况下是10秒
set host "192.168.33.124" //设置变量
set username "root"
set pass "123456"
spawn ssh $username@$host //spawn:是进入expect环境后才可以执行的expect内部命令,如果没有装expect或者直接在默认的SHELL下执行是找不到spawn命令的。它主要的功能是给ssh运行进程加个壳,用来传递交互指令
expect "*password*" {send "$pass\r"} //这里的expect也是expect的一个内部命令,这个命令的意思是判断上次输出结果里是否包含“password”的字符串,如果有则立即返回;否则就等待一段时间后返回,这里等待时长就是前面设置的30秒
interact //执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。如果没有这一句登录完成后会退出,而不是留在远程终端上

在上述的示例中,涉及到expect中一个非常重要的概念——模式-动作;即上述expect "*password*" {send "$password\r"}这句代码表达出来的含义。简单的说就是匹配到一个模式,就执行对应的动作;匹配到password字符串,就输入密码。你可能也会看到这样的代码:

expect {
"password" {
send "$pass\r"
exp_continue
}
eof
{
send "eof"
}
}

其中exp_continue表示循环式匹配,通常匹配之后都会退出语句,但如果有exp_continue则可以不断循环匹配,输入多条命令,简化写法。

很多时候,我们需要传递参数到脚本中,现在通过下面这段代码来看看如何在expect中使用参数:

#!/usr/bin/expect
if {$argc < 3} {
puts "Usage:cmd <host> <username> <password>"
exit 1
}
set timeout -1
set host [lindex $argv 0]
set username [lindex $argv 1]
set pass [lindex $argv 2]
spawn ssh $username@$host
expect "*password*" {send "$pass\r"}
interact

在expect中,$argc表示参数个数,而参数值存放在$argv中,比如取第一个参数就是[lindex $argv 0],依此类推。

五、expect应用实例
1.传参式ssh登陆指定主机

#!/usr/bin/expect -f
set ip [ lindex $argv 0 ] //接收第一个参数,并设置IP
set pass [ lindex $argv 1 ] //接收第二个参数,并设置密码
set timeout 10 //设置超时时间
spawn ssh root@$ip //发送ssh请求
expect { //返回信息匹配
"*yes/no" { send "yes\r"; exp_continue} //第一次ssh连接会提示yes/no,自动发送yes
"*password:" { send "$pass\r" } //出现密码提示,发送密码
}
interact //交互模式,用户会停留在远程服务器上面

2.利用expect批量ssh互信
编写hosts文本用于存放主机信息,格式如下:

编写脚本,如下所示:

#!/bin/bash

# 判断id_rsa密钥文件是否存在
if [ ! -f ~/.ssh/id_rsa ];then
ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
else
echo "id_rsa has created ..."
fi

#分发到各个节点,这里分发到host文件中的主机中.
while read line
do
user=`echo $line | cut -d " " -f 2`
ip=`echo $line | cut -d " " -f 1`
passwd=`echo $line | cut -d " " -f 3`

expect <<EOF
set timeout 10
spawn ssh-copy-id $user@$ip
expect {
"yes/no" { send "yes\n";exp_continue }
"password" { send "$passwd\n" }
}
expect "password" { send "$passwd\n" }
EOF
done < hosts

由于是做实验,只在hosts文件里放了一台机器的信息,如果是很多太机器的话,可以把其他机器的信息按照相同的格式放入hosts文件中,运行该脚本的机器都可以免密ssh登陆其他机器,如果需要相互之间都能免密登陆,则每台机器都执行该脚本,可以结合saltsatck自动化运维工具来使每台机器都执行该脚本。

本文作者:韩憨

本文链接:https://www.cnblogs.com/hanby/p/15524774.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   韩憨  阅读(2034)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
//看板娘

剑桥

点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 隔离 (Studio Live Duet) 陈凯咏,林家谦
  2. 2 明知做戏 吴雨霏
  3. 3 残酷游戏 卫兰
  4. 4 你,好不好? 周兴哲
  5. 5 我可以 蔡旻佑
  6. 6 云烟成雨 房东的猫
  7. 7 说散就散 JC 陈咏桐
  8. 8 我配不上你 夏天Alex
  9. 9 不再联系 夏天Alex
  10. 10 等我先说 夏天Alex
  11. 11 我知道他爱你 夏天Alex
  12. 12 多想在平庸的生活拥抱你 隔壁老樊
  13. 13 这一生关于你的风景 隔壁老樊
  14. 14 我曾 隔壁老樊
  15. 15 关于孤独我想说的话 隔壁老樊
  16. 16 过客 周思涵
  17. 17 备爱 周思涵
  18. 18 嚣张 en
  19. 19 海口 后弦
你,好不好? - 周兴哲
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 周兴哲/吴易纬

作曲 : 周兴哲

编曲:陈建骐

是不是 还那么爱迟到

熬夜工作又睡不好

等你完成你的目标

要戒掉逞强的嗜好

都怪我

把自尊放太高

没有把你照顾好

骄傲是脆弱的外表

最怕我的心你不要

能不能继续对我哭

对我笑对我好

继续让我为你想

为你疯陪你老

你好不好好想知道

别急着把回忆都丢掉

我只需要你在身边

陪我吵陪我闹

用好的我

把过去坏的我都换掉

好想听到你坚决说爱我

可惜回不去那一秒

你 好不好

天知道我快要受不了

后悔 钻进心里烧

拥抱 再多一次就好

你要的我都做得到

能不能继续对我哭

对我笑 对我好

继续让我为你想

为你疯 陪你老

给你的好还要不要

答案我却不敢揭晓

我只需要你在身边

陪我吵 陪我闹

别用离开教我

失去的人最重要

别说 你曾经爱过我

让我们回到那一秒

你好不好

能不能继续对我哭

对我笑 对我好

继续让我为你想

为你疯 陪你老

你好不好 我好想知道

别急着把我的爱丢掉

我只需要你在身边

陪我吵 陪我闹

别用离开教我

失去的人最重要

别说 你曾经爱过我

让我们回到那一秒

你 好不好?