shell脚本——expect命令_expect 在shell脚本中用法-程序员宅基地

技术标签: shell脚本  .sh文件调用.sh文件 .exp文件  expect完成ssh并做操作后退出  expect安装  

一、对expect的基本了解

 我们通过Shell可以实现简单的控制流功能,如:循环、判断等。但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如telnet服务器等进行交互的功能。而expect就使用来实现这种功能的工具。

       expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。expect是不断发展的,随着时间的流逝,其功能越来越强大,已经成为系统管理员的的一个强大助手。expect需要Tcl编程语言的支持,要在系统上运行expect必须首先安装Tcl。

二、expect的安装

expect是在Tcl基础上创建起来的,所以在安装expect前我们应该先安装Tcl。

(一)Tcl 安装

主页: http://www.tcl.tk

下载地址: http://www.tcl.tk/software/tcltk/downloadnow84.tml

1.下载源码包

 wget http://nchc.dl.sourceforge.net/sourceforge/tcl/tcl8.4.11-src.tar.gz  

 

2.解压缩源码包 

tar xfvz tcl8.4.11-src.tar.gz  

 

3.安装配置

  1. cd tcl8.4.11/unix  
  2. ./configure --prefix=/usr/tcl --enable-shared  
  3. make  
  4. make install  

注意:

1、安装完毕以后,进入tcl源代码的根目录,把子目录unix下面的tclUnixPort.h copy到子目录generic中。

2、暂时不要删除tcl源代码,因为expect的安装过程还需要用。

(二)expect 安装 (需Tcl的库)

主页: http://expect.nist.gov/

1.下载源码包 wget http://sourceforge.net/projects/expect/files/Expect/5.45/expect5.45.tar.gz/download

 

2.解压缩源码包

tar xzvf expect5.45.tar.gz  

 

3.安装配置 

  1. cd expect5.45  
  2. ./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-tclinclude=../tcl8.4.11/generic  
  3. make  
  4. make install  
  5. ln -s /usr/tcl/bin/expect /usr/expect/bin/expect  

shell脚本实现expect的安装

########################################################

#(1)这部分实现expect的安装

#(2)expect 需要 依赖tcl的库

#(3)expect的位置 /use/expect/bin/expect; tcl位置 /usr/tcl/bin/tclsh8.4

#(4)注意:脚本每执行一次 就会安装一次

########################################################

function testInstal_pack() {

echo -e "\033[32m-----------------------------------------------\033[0m"

echo "This is going to install package $1!"

if [ $1 == "tcl" ]

then

echo "tcl tcl"

tar -xzf $TCLTAR_PATH -C $RUN_PATH

cd $TCL_PATH/unix

./configure --prefix=/usr/tcl --enable-shared

make && make install

cp $TCL_PATH/unix/tclUnixPort.h $TCL_PATH/generic/

fi

 

if [ $1 == "expect" ]

then

echo "aa"

tar -xzf $EXPECTTAR_PATH -C $RUN_PATH

cd $EXPECT_PATH

./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-tclinclude=$TCL_PATH/generic

make && make install

ln -s /usr/tcl/bin/expect /usr/expect/bin/expect

fi

}

#testInstal_pack openssl

testInstal_pack tcl

testInstal_pack expect

三、expect的原理

Linux expect 脚本的使用

Expect的原理:

     Expect脚本语言自动提交输入到交互程序,它的工作原理是等待特定字符串,并发送或者响应相应的字符串。以下四个expect命令用于任何自动化的过程。

1、spawn:启动命令

2、expect:等待来自进程的特定的字符串

3、send:发送字符串到进程

4、interact:允许用户交互

3.1 首行加上/usr/bin/expect 但是在根据上述方式安装后 应该为#!/usr/expect/bin/expect

3.2 spawn: 后面加上需要执行的shell命令,比如说spawn sudo touch testfile

3.3 expect: 只有spawn执行的命令结果才会被expect捕捉到,因为spawn会启动一个进程,只有这个进程的相关信息才会被捕捉到,主要包括:标准输入的提示信息,eof和timeout。

3.4 send和send_user:send会将expect脚本中需要的信息发送给spawn启动的那个进程,而send_user只是回显用户发出的信息,类似于shell中的echo而已。

四、expect的使用实例

1、使用expect工具ssh登录远程服务器并执行命令操作

远程交互从服务器Assh到服务器B上,然后执行服务器B上的命令

#!/usr/expect/bin/expect -f

 

set ipaddress [lindex $argv 0]

set port [lindex $argv 1]

set username [lindex $argv 2]

set passwd [lindex $argv 3]

set timeout 30

 

if {$argc != 4} {

send "usage ./account.sh \$ipaddress \$port \$username \$passwd\n"

exit

}

 

spawn ssh $ipaddress -p$port -l$username

expect {

"yes/no" { send "yes\r";exp_continue }

"password:" { send "$passwd\r" }

}

expect -re "\](\$|#) "

send "iptables -F\r"

expect -re "\](\$|#) "

send "exit\r"

4.1 默认情况下 timeout是10秒,但是在ssh远程登录的时候建议改为30秒,否则会报错“expect: spawn id exp4 not open,”

4.2 输入的参数的数目,可以通过$argc得到;

4.3 参数存在$argv当中,比如取第一个参数就是[lindex $argv 0];并且如果需要计算的话必须用expr,如计算2-1,则必须用[expr 2-1];

4.4 下面我们来看一些expect的一些内部参数:

exp_continue [-continue_timer]

             The command exp_continue allows expect itself to continue executing rather than returning as it  normally

             would.  By  default  exp_continue  resets the timeout timer. The -continue_timer flag prevents timer from

             being restarted.

exp_version [[-exit] version]

             is useful for assuring that the script is compatible with the current version of Expect.

             With  no  arguments, the current version of Expect is returned.  This version may then be encoded in your

             script.  If you actually know that you are not using features of recent versions, you can specify an ear-

             lier version.

执行结果如下:

[root@slave1 workspace]# ./dotask.exp 192.168.1.93

usage ./account.sh $ipaddress $port $username $passwd

[root@slave1 workspace]# ./dotask.exp 192.168.1.93 22 root asdfgh

spawn ssh 192.168.1.93 -p22 -lroot

[email protected]'s password:

Last login: Fri Jun 15 15:08:49 2018 from 192.168.1.177

[root@J01051386 ~]# iptables -F

[root@J01051386 ~]# [root@slave1 workspace]#

 

参考的链接:http://blog.sina.com.cn/s/blog_5432f2730100vcql.html

Expect说白了就是一个实现人机交互的命令工具,可以抓取和相应用户输入,也可以模拟用户输出。

 

比如你有n台服务器需要维护,要登录到所有的服务器上执行某项操作(如添加用户、修改一个用户的密码),如果按传统方法,一个一个去登录敲命令那就太麻烦了。可以通过expect写成shell脚本来批量处理,具体如下:

如果系统里没有expect请自行到官网下载安装:http://expect.sourceforge.net/

1、创建服务器列表配置文件:

[root@localhost ~]# vi server_list.conf

192.168.0.10 22 root 123456

192.168.0.11 22 root 123456

192.168.0.12 60008 root 123456

 

说明:配置文件有4列,以空格分割:服务器IP ssh端口号 用户名 密码

2、编写expect脚本:

[root@localhost ~]# vi dotask.exp

#!/usr/bin/expect -f

set ipaddress [lindex $argv 0]

set port [lindex $argv 1]

set username [lindex $argv 2]

set passwd [lindex $argv 3]

set timeout 30

spawn ssh $ipaddress -p$port -l$username

expect {

"yes/no" { send "yes\r";exp_continue }

"password:" { send "$passwd\r" }

}

expect -re "\](\$|#) "

send "touch test \r"

expect -re "\](\$|#) "

send "exit\r"

 

说明:这里只实现了登录服务器后在当前目录创建了一个test文件,具体需求请自行修改添加命令

 

3、批量执行

其实只要写好第2步的脚本就可以通过下面命令执行一台服务器的处理:

[root@localhost ~]# expect dotask.exp 192.168.0.10 22 root 123456

但为了能批量处理n台,再写个shell脚本就行了,如下:

[root@localhost ~]# vi doexcute.sh

#!/bin/bash

 

filename="server_list.conf"

while read line

do

  #echo $line;

  expect dotask.exp$line

done < $filename

 

说明:读取配置文件,循环执行

最后,其他具体的使用方法参见expect手册

 

=================================================

实用工具:autoexpect

=================================================

如果自己懒得写expect代码,则可以用autoexpect生成。autoexpect工具是用expect写成的一个工具脚本,它可以录制你执行的操作、命令、键盘输入等等,之后自动生成expect脚本。

autoexpect脚本代码见:http://blog.sina.com.cn/s/blog_5432f2730100vcqn.html

使用方法:

1、把上面链接里的autoexpect代码保存成文件:autoexpect.exp

2、执行下面命令进行录制:

[root@localhost ~]# expect autoexpect.exp -p

 说明:执行完上面命令后就可以进行你需要的操作了,需要结束录制时,用exit退出即可。

3、录制完后,会在当前目录生成一个script.exp文件,这个文件就是录制好的expect脚本了。是直接拿来使用,还是再改改,或是学习用,就看你自己的需要了。

 

2、在shell语句中完成赋值操作,并做判断

http://blog.51cto.com/maomaochong/1690753

注意:

1. if判断中[]与if间需要有空格;

2. if判断语句中判断语句与[]两边都要有空格;

3. If判断语句中=号两边要有空格;

例如##ping -c 3 -i 0.1 192.168.1.32 && result=0||result=1;if [ "${result}"  =  0 ];then echo success;fi

例如:当查看文件中是否有TLSCACertificatePath 开头的行,若有退出程序,若无则在最后一行加入。

cat sldap.conf|grep ^TLSCACertificatePath && result=0||result=1;echo ${result};if [ "${result}" = 0 ];then exit 1;else sed -i '$a TLSCACertificatePath' sldap.conf;fi

例如:当查看文件中是否有TLSCACertificatePath 开头的行,若有不做处理,若无则在最后一行加入。

cat sldap.conf|grep ^TLSCACertificatePath && result=0||result=1;echo ${result};if [ "${result}" = 1 ];then sed -i '$a TLSCACertificatePath' sldap.conf;fi

Shell脚本中expect写入最终格式(注意路径和转义):

send "cat $SERVERLDAP_PATH/sldap.conf|grep ^TLSCACertificatePath && result=0||result=1;if \[ \"$\{result\}\" = 1 \];then sed -i '\$a TLSCACertificatePath /usr/local/etc/openldap/certs' $SERVERLDAP_PATH/sldap.conf;fi\r"

五、shell脚本调用expect脚本(即.sh文件调用.exp文件)

[root@slave1 workspace]# cat test.sh

#!/bin/sh

./dotask.exp 192.168.1.93 22 root asdfgh

[root@slave1 workspace]# cat dotask.exp

代码见 四、expect的使用实例1

六、shell脚本调用shell脚本(即.sh文件调用.sh文件)

https://blog.csdn.net/simple_the_best/article/details/76285429

hello.sh

#!/bin/bash

wor="world"

echo "hello `source ./world.sh`"

world.sh

#!/bin/bash

echo $wor

参考链接:

http://blog.sina.com.cn/s/blog_5432f2730100vcql.html

https://www.cnblogs.com/lixigang/articles/4849527.html

https://blog.csdn.net/nero_g/article/details/53945654

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_42167759/article/details/80708417

智能推荐

记录Linux安装Oracle19c_debian 安装 oracle19c-程序员宅基地

文章浏览阅读712次。最近单位要求本渣学习服务器脚本编写完成定点市级机构下发的数据库表导入项目服务器数据库,按工作顺序就先打算在自己笔记本电脑上通过虚拟机来模拟生产环境,部署虚拟环境后安装Linux版本Oracle19c数据库。经过数天研究终完成安装,记录如下。安装准备:1、虚拟软件 Oracle VM VirtualBox2、镜像 CentOS-7-x86_64-Minimal-2009.iso3、Xshell 7.04、Xftp 7.05、Xmanager Enterprise 56、LINUX._debian 安装 oracle19c

Halcon分类器之高斯混合模型分类器_训练高斯混合模型分类器-程序员宅基地

文章浏览阅读2k次,点赞2次,收藏20次。Halcon分类器示例自我理解看了很多网上的例子,总有一种纸上得来终觉浅,绝知此事要躬行的感觉。说干就干,将Halcon自带分类器例子classify_metal_parts.hdev按照自己的理解重新写一遍,示例中的分类器是MLP(多层感知机),我将它改变为GMM(高斯混合模型)。希望可以帮助刚入门的同学学习理解,大神请绕路吧,当然也喜欢各位看官帮我找出不足之处,共同进步。谢谢!分类效果如图..._训练高斯混合模型分类器

Office转PDF工具类_"officetopdf.wordtopdf(\"d:\\\\1234.doc\", \"d:\\\-程序员宅基地

文章浏览阅读819次。使用Jacob转换office文件,Jacob.dll文件需要放到jdk\bin目录下Jacob.dll文件下载地址https://download.csdn.net/download/zss0101/10546500package com.zss.util;import java.io.File;import com.jacob.activeX.ActiveXComponent;..._"officetopdf.wordtopdf(\"d:\\\\1234.doc\", \"d:\\\\1234.pdf\");"

redis实现队列_redistemplate convertandsend方法实现队列-程序员宅基地

文章浏览阅读1k次,点赞30次,收藏30次。上面的例子我们已经了一个简易的消息队列。我们继续思考一个现实的场景,假定这些是一些游戏商品,它需要添加"延迟销售"特性,在未来某个时候才可以开始处理这些游戏商品数据。那么要实现这个延迟的特性,我们需要修改现有队列的实现。在消息数据的信息中包含延迟处理消息的执行时间,如果工作进程发现消息的执行时间还没到,那么它将会在短暂的等待之后重新把消息数据推入队列中。(延迟发送消息)_redistemplate convertandsend方法实现队列

java基础-程序员宅基地

文章浏览阅读287次,点赞5次,收藏5次。java基础篇

使用gparted对linux根目录扩容(windows+linux双系统)_双系统linux扩容-程序员宅基地

文章浏览阅读298次。linux扩容根目录与/home_双系统linux扩容

随便推点

Python使用pika调用RabbitMQ_python pika 通过主机名称来访问mq-程序员宅基地

文章浏览阅读388次。定义RabbitMQ类import jsonimport osimport sysimport pikafrom Data import Datafrom MongoDB import MongoDBfrom constants import *class RabbitMQ: def __init__(self, queue_name): """ 初始化队列对象 :param queue_name: 队列名称 "_python pika 通过主机名称来访问mq

Python利用openpyxl处理excel文件_在 python 中可以通過 openpyxl 套件來很好的操作 excel 讀寫-程序员宅基地

文章浏览阅读568次。**openpyxl简介**openpyxl是一个开源项目,openpyxl模块是一个读写Excel 2010文档的Python库,如果要处理更早格式的Excel文档,需要用到其它库(如:xlrd、xlwt等),这是openpyxl比较其他模块的不足之处。openpyxl是一款比较综合的工具,不仅能够同时读取和修改Excel文档,而且可以对Excel文件内单元格进行详细设置,包括单元格样式等内容,甚至还支持图表插入、打印设置等内容,使用openpyxl可以读写xltm, xltx, xlsm, xls_在 python 中可以通過 openpyxl 套件來很好的操作 excel 讀寫

Unity判断某个物体是否在某个规定的区域_unity判断物体在范围内-程序员宅基地

文章浏览阅读1.4w次,点赞7次,收藏56次。Unity自带的两种写法:①物体的位置是否在某个区域内Vector3 pos = someRenderer.transform.position;Bounds bounds = myBoxCollider.bounds;bool rendererIsInsideTheBox = bounds.Contains(pos);②物体的矩形与区域的矩形是否交叉Bounds rendererBo..._unity判断物体在范围内

[深度学习] 使用深度学习开发的循线小车-程序员宅基地

文章浏览阅读295次,点赞6次,收藏4次。报错:Unable to find image 'openexplorer/ai_toolchain_centos_7_xj3:v2.3.3' locally。报错: ./best_line_follower_model_xy.pth cannot be opened。可以看到生成的文件 best_line_follower_model_xy.pth。报错:Module onnx is not installed!安装onox,onnxruntime。这是由于没有文件夹的写权限。

MDB-RS232测试NAYAX的VPOS刷卡器注意事项-程序员宅基地

文章浏览阅读393次,点赞10次,收藏8次。MDB-RS232测试NAYAX的VPOS非现金MDB协议刷卡器注意事项

Pytorch和Tensorflow,谁会笑到最后?-程序员宅基地

文章浏览阅读2.5k次。作者 |土豆变成泥来源 |知秋路(ID:gh_4a538bd95663)【导读】作为谷歌tensorflow某项目的Contributor,已经迅速弃坑转向Pytorch。目前Ten..._pytorch与tensorflow

推荐文章

热门文章

相关标签