Linux expect 详解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux expect 详解相关的知识,希望对你有一定的参考价值。

参考技术A 首先检查系统是否自带了expect程序, 一般在 系统的/usr/bin目录下, 如果没有自带expect, 那么需要自行安装expect. 这里仅介绍ubuntu和redhat系列linux的安装方法。
ubuntu系列

redhat系列

说明:

Expect—百科篇命令

expect(1) - Linux man page

1-26-1-expect无交互式-正则表达式

大纲:

1、expect环境搭建及脚本编写

概述

expect脚本详解

expect环境搭建

expect脚本实现ssh远程连接

expect脚本实现ssh远程连接(通过shell传递参数)

2、正则表达式详解及实例

详解

普通正则

扩展正则

案例

1、expect环境搭建及脚本编写

一、概述

我们通过Shell可以实现简单的控制流功能,如:循环、判断等。

但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如ssh服务器等进行交互的功能。

expect就使用来实现这种功能的工具。

expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。

expect的作者Don Libes在1990年 开始编写Expect时对Expect做有如下定义:

1.Expect是一个用来实现自动交互功能的软件套件。

2. Expect则可以根据程序的提示模拟标准输入提供给程序需要的输入来实现交互程序执行。

3.甚至可以实现实现简单的BBS聊天机器人。

Expect是不断发展的,随着时间的流逝,其功能越来越强大,已经成为系统管理员的的一个强大助手。Expect需要Tcl编程语言的支持,要在系统上运行Expect必须首先安装Tcl。

源码下载链接

http://jaist.dl.sourceforge.net/project/tcl/Tcl/8.6.4/tcl8.6.4-src.tar.gz

http://sourceforge.net/projects/expect/files/Expect/5.45/expect5.45.tar.gz/download

二、expect脚本详解

1、与编写shell脚本一样,第一行要告诉命令解释器执行这个脚本的程序是谁。

#!/usr/bin/expect #expect程序的路径

这一行告诉操作系统脚本里的代码使用那一个主程序来执行。

2、当然,在无交互式的脚本中,也需要我们设置一个反应时间,当超过这个时间,仍没有反应时脚本就会自动断开连接,不会一直等待下去,基本单位:秒(s)

set timeout 30

set 设置变量

这是设置超时时间的,现在你只要记住他的计时单位是:秒 。

timeout  -1 为永不超时

3、在expect脚本中,使用spawn(expect内部命令)来向执行交互式命令

spawn ssh root@192.168.171.122

如果没有装expect或者直接在默认的SHELL下执行是找不到spawn命令的。

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

4、交互命令执行完后,当然是需要expect脚本来根据输出判断,来确定模拟输入的数据了!这时就用到了expect(expect内部命令),格式如下:

expect {

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

    "password" { send "123456\\r"}

}

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

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

"yes/no" 判断上一条输出中若含有字符串"yes/no"时,send就会模拟输入,发送"yes" 给终端,但是需要加上结束符 \\r 依次来确定,本次输入结束。exp_continue继续执行判断。

5、send

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

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

6、exp_continue

继续执行接下来的交互操作

7、interact

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

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

8、$argv 参数数组

expect脚本可以接收从shell传递过来的参数,使用

[lindex $argv n] 获得第n+1个参数(n从0开始,分别代表第一个($0),第二个($1),第三个($2)...参数)

$argv 0

三、环境搭建:

1、上传下载的tcl和expect源码包

2、安装tcl

2.1、解压tcl源码包到/usr/src目录下

tar -zxf tcl8.6.4-src.tar.gz -C /usr/src

2.2 进入源码目录,在源码目录中,有很多系统支持,见下图(linux、windows、ios):

wps5D78.tmp

2.3 (linux系统)进入unix目录,配置源码安装目录/usr/local/tcl,并开启shared

cd /usr/src/tcl8.4.20/unix

./configure --prefix=/usr/local/src --enbale-shared

echo $? #检查上一条命令是否执行成功

2.4 编译并安装

make -j 4 && echo $?

make install && echo $?

2.5 拷贝接口头文件到generic目录下

cp /usr/src/tcl8.4.20/unix /usr/src/tcl8.4.20/generic

3、安装expect

3.1 解压expect5.45.tar.gz到/usr/src目录下

tar -zxf expect5.45.tar.gz -C /usr/src

3.2 切换目录,并配置源码:指定安装目录为/usr/local/expect 指定tcl库目录,指定tcl头文件目录

./configure  --prefix=/usr/local/expect --with-tcl=/usr/local/tcl/bin/lib --with-tclinclude=/usr/src/tcl8.4.20/generic

echo $?

3.3 编译并安装

make -j 4 && echo $?

make install && echo $?

3.4 优化程序

expect是tcl的命令,所以我们需要将expect软连接到expect目录下

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

为了编写脚本时,书写方便,我们可以将expect软连接到/bin或/usr/bin等目录下

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

详细见下图:

注:为了便于截图和后期检查,我将配置、编译、安装过程信息分别保存在了.log日志文件中

wps5D79.tmp

3、编写expect脚本,实现无交互式ssh远程连接

vim ssh.exp #使用exp结尾,便于以后管理和识别

chmod +x ssh.exp #对脚本添加可执行权限,也可使用expect ssh.exp

./ssh.exp

详情见下图:

wps5D7A.tmp

4、编写脚本,通过shell传递的参数实现ssh远程登录

vim argv_ssh.exp

cat argv_ssh.exp

expect argv_ssh.exp 192.168.171.63 123456

详情见下图:

wps5D8A.tmp

2、正则表达式详解及实例

一、详解:

Linux Shell 是以一串字符做为表达式向系统传达意思,

元字符:具有特殊含义的字符

用来阐述字符表达式意义的字符,元字符就是描述字符的字符.

用于对字符表达式的内容.

转换及操作的信息进行描述.

介绍:符合一定规则的表达式

作用:文本查询和字符的操作,可以匹配文本的一个字符或字符集合.

字符串(匹配.切割.替换.获取)

所以学习正则表达式,就是在学习一些特殊符号的使用。

好处:可以简化对字符串的复杂操作。弊端:符号定义越多,正则越长,阅读性越差。

应用范围:

编程语言:Java Perl Python

shell工具:

grep 从特定文件中或标准输入中查找含有某个字符串的行

sed 从输入中读取信息,经过编辑后输出

awk  文本处理

数据库:MySql

grep命令

使用grep与正则表达式结合搜索数据,将匹配的行打印出来

Usage: grep [OPTION]... PATTERN [FILE]...

PATTERN可以是字符串,也可以是变量,还可以是正则表达式

当你的模式包含空格时就需要使用双引号将模式引起来,空格后面容易被误认为是文件名

  grep hello world a.txt  如果你不把hello world加上引号那么就会认为world 是一个文件;

grep支持多文件查询

OPTIONS

-E  扩展的正则表达式 egrep(PATTERN is an extended regular expression (ERE))

-i  忽略大小写 ignore case distinctions

-v 显示不匹配的行 select non-matching lines

-F #fgrep(PATTERN is a set of newline-separated fixed strings)

-e --regexp=PATTERN #use PATTERN for matching

-f --file=FILE  #obtain PATTERN from FILE

-l #print only names of FILEs containing matches

-L #print only names of FILEs containing no match

-q #suppress all normal output(保持沉默)

-s #suppress error messages

-w --word-regexp  #force PATTERN to match only whole words

-x --line-regexp  #force PATTERN to match only whole lines

-h #省略文件的名称 suppress the file name prefix on output

-n #列出所有的匹配行,并显示行号print line number with output lines

-c #只显示匹配行数量print only a count of matching lines per FILE

正则表达式组成

一般字符:没有特殊意义的字符

特殊字符:元字符meta,在正则中有特殊意义

POSIX BRE与ERE中都有的meta字符:常见元字符:

\\ 转义,打开关闭后续特殊字符的含义。如\\(...\\)与\\{...\\}

. 匹配任何单个字符(除NULL)

* 匹配其前的任意多个字符或没有,在通配符中,*匹配任意字符

^ 匹配后面字符或字符串开头的行,^在[]中,表示不匹配对应数值

$ 匹配前面字符或字符串结尾的行

[] 匹配中括号中包含的任意一个字符,其中可用连字符(-)指的连续字符的范围;^符号若出现在方括号的第一个位置,则表示匹配不在列表中的任一字符,

普通正则:

\\{n,m\\}   :区间表达式,匹配第n次出现到第m次出现的字符

\\(\\) 保留空间,可以将最多9个独立的子模式存储在单个模式中。如\\(ab\\).*\\1 : 指匹配ab组合的两次出现,中间可存在任意数目的字符。

\\n 重复在()内的第n个子模式至此点的模式

扩展正则:

{n,m} 与BRE的\\{n,m\\}功能相同

+ 匹配前面正则表达式的一个或多个拓展

? 匹配前面正则表达式零个或一个扩展

| 匹配|符号前后的正则表达式

() 匹配括号括起来正则表达式群

简单正规表达式匹配案例

china  :  匹配此行中任意位置有china字符的行

^china : 匹配以china开头的行

china$ : 匹配以china结尾的行

^china$ : 匹配仅有china五个字符的行

[Cc]hina : 匹配含有China或china的行

Ch.na : 匹配包含Ch两字母并且其后紧跟一个任意字符之后又有na两个字符的行

China

Chana

Ch.*na : 匹配一行中含Ch字符,并且其后跟0个或者多个字符,再继续跟na两字符

[1234] 匹配1,2,3,4中的一个

[1-9] 数字1-9中的一个

[A-Za-z] 所有字母

[^0-9] 一个非数字的字符

A\\{2\\}B 匹配AAB

A\\{4,\\}B 匹配A出现至少4次之后有个B的字符串

A\\{2,4\\}B 匹配A出现在2至4次之间,之后有个B的字符串

案例:

显示/proc/meminfo以s开头的行,不分大小写

grep -i "^s" /proc/meminfo

wps5D8B.tmp

显示/etc/passwd中不以/bin/bash结尾的行

grep -v "/bin/bash$" /etc/passwd

wps5D8C.tmp

查找以root开头的行/etc/passwd 显示行号

grep "^root" -n /etc/passwd

wps5D8D.tmp

查找包含数字的行

grep "[0-9]" /etc/yum.repos.d/rhel7.repo

wps5D8E.tmp

脚本 过滤网站域名

grep "^https\\{0,1\\}.*\\..*" url.txt

grep "^https\\{0,1\\}.*\\..*\\.com" url.txt

grep "^https\\{0,1\\}://.*\\..*\\.com" url.txt

grep "^https\\{0,1\\}://.*\\.baidu.*\\.com" url.txt

wps5D8F.tmp

grep "\\(https\\)\\{2\\}" url.txt

wps5D90.tmp

匹配ip地址:

ifconfig | grep "[0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*"

wps5DA1.tmp

ifconfig | grep "[0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*" | head -1 | awk {\'print $2\'}

wps5DA2.tmp

以上是关于Linux expect 详解的主要内容,如果未能解决你的问题,请参考以下文章

linux expect详解(ssh自动登录)

Shell编程之Expect免交互语句详解

linux spawn命令

shell脚本交互:expect学习笔记及实例详解

spawn类expect方法详解

1-26-1-expect无交互式-正则表达式