`

(转)expect学习笔记及实例详解

阅读更多
expect学习笔记及实例详解
 参考:http://myunix.blog.51cto.com/191254/1095074
1. expect 是基于tcl 演变而来的,所以很多语法和tcl 类似,基本的语法如下
所示:
1.1 首行加上/usr/bin/expect
1.2 spawn: 后面加上需要执行的shell 命令,比如说spawn sudo touch testfile
1.3 expect: 只有spawn 执行的命令结果才会被expect 捕捉到,因为spawn 会启
动一个进程,只有这个进程的相关信息才会被捕捉到,主要包括:标准输入的提
示信息,eof 和timeout。
1.4 send 和send_user:send 会将expect 脚本中需要的信息发送给spawn 启动
的那个进程,而send_user 只是回显用户发出的信息,类似于shell 中的echo 而
已。
 
2. 一个小例子,用于linux 下账户的建立:
filename: account.sh,可以使用./account.sh newaccout 来执行;
1 #!/usr/bin/expect
2
3 set passwd "mypasswd"
4 set timeout 60
5
6 if {$argc != 1} {
7 send "usage ./account.sh \$newaccount\n"
8 exit
9 }
10
11 set user [lindex $argv [expr $argc-1]]
12
13 spawn sudo useradd -s /bin/bash -g mygroup -m $user
14
15 expect {
16 "assword" {
17 send_user "sudo now\n"
18 send "$passwd\n"
19 exp_continue
20 }
21 eof
22 {
23 send_user "eof\n"
24 }
25 }
26
27 spawn sudo passwd $user
28 expect {
29 "assword" {
30 send "$passwd\n"
31 exp_continue
32 }
33 eof
34 {
35 send_user "eof"
36 }
37 }
38
39 spawn sudo smbpasswd -a $user
40 expect {
41 "assword" {
42 send "$passwd\n"
43 exp_continue
44 }
45 eof
46 {
47 send_user "eof"
48 }
49 }
 
3. 注意点:
 
第3 行: 对变量赋值的方法;
第4 行: 默认情况下,timeout 是10 秒;
第6 行: 参数的数目可以用$argc 得到;
第11 行:参数存在$argv 当中,比如取第一个参数就是[lindex $argv 0];并且
如果需要计算的话必须用expr,如计算2-1,则必须用[expr 2-1];
第13 行:用spawn 来执行一条shell 命令,shell 命令根据具体情况可自行调整;
有文章说sudo 要加-S,经过实际测试,无需加-S 亦可;
第15 行:一般情况下,如果连续做两个expect,那么实际上是串行执行的,用。expect 与“{ ”之间直接必须有空格或则TAB间隔,否则会出麻烦,会报错invalid command name "expect{" 
例子中的结构则是并行执行的,主要是看匹配到了哪一个;在这个例子中,如果
你写成串行的话,即
expect "assword"
send "$passwd\n"
expect eof
send_user "eof"
那么第一次将会正确运行,因为第一次sudo 时需要密码;但是第二次运行时由于
密码已经输过(默认情况下sudo 密码再次输入时间为5 分钟),则不会提示用户
去输入,所以第一个expect 将无法匹配到assword,而且必须注意的是如果是
spawn 命令出现交互式提问的但是expect 匹配不上的话,那么程序会按照timeout
的设置进行等待;可是如果spawn 直接发出了eof 也就是本例的情况,那么expect
"assword"将不会等待,而直接去执行expect eof。
这时就会报expect: spawn id exp6 not open,因为没有spawn 在执行,后面的
expect 脚本也将会因为这个原因而不再执行;所以对于类似sudo 这种命令分支
不定的情况,最好是使用并行的方式进行处理;
第17 行:仅仅是一个用户提示而已,可以删除;
第18 行:向spawn 进程发送password;
第19 行:使得spawn 进程在匹配到一个后再去匹配接下来的交互提示;
第21 行:eof 是必须去匹配的,在spawn 进程结束后会向expect 发送eof;如果
不去匹配,有时也能运行,比如sleep 多少秒后再去spawn 下一个命令,但是不
要依赖这种行为,很有可能今天还可以,明天就不能用了;
 
4. 其他
下面这个例子比较特殊,在整个过程中就不能expect eof 了:
1 #!/usr/bin/expect
2
3 set timeout 30
4 spawn ssh 10.192.224.224
5 expect "password:"
6 send "mypassword\n"
7 expect "*$"
send "mkdir tmpdir\n" #远程执行命令用send发送,不用spawn
9 expect "*$" #注意这个地方,要与操作系统上环境变量PS1相匹配,尤其是有PS1有空格的情况下,一定在expct "*$ "把空格加上,加不上你就完蛋了。我试过。
这个例子实际上是通过ssh 去登录远程机器,并且在远程机器上创佳一个目录,
我们看到在我们输入密码后并没有去expect eof,这是因为ssh 这个spawn 并没
有结束,而且手动操作时ssh 实际上也不会自己结束除非你exit;所以你只能
expect bash 的提示符,当然也可以是机器名等,这样才可以在远程创建一个目
录。
注意,请不要用spawn mkdir tmpdir,这样会使得上一个spawn 即ssh 结束,那
么你的tmpdir 将在本机建立。
当然实际情况下可能会要你确认ssh key,可以通过并行的expect 进行处理,不
多赘述。
 
5. 觉得bash 很多情况下已经很强大,所以可能用expect 只需要掌握这些就好了,
其他的如果用到可以再去google 了。
 
源代码图片:
 
 
 
 
 

6 \实例:下面这个脚本是完成对单个服务器scp任务。

 1: #!/usr/bin/expect
 2: 
 3: set timeout 10
 4: set host [lindex $argv 0]
 5: set username [lindex $argv 1]
 6: set password [lindex $argv 2]
 7: set src_file [lindex $argv 3]
 8: set dest_file [lindex $argv 4]
 9: 
10: spawn scp  $src_file $username@$host:$dest_file
 11: expect {
 12:     "(yes/no)?"
 13:         {
 14:             send "yes\n"
 15:             expect "*assword:" { send "$password\n"}
 16:         }
 17:     "*assword:"
 18:         {
 19:             send "$password\n"
 20:         }
 21:     }
 22: expect "100%"
 23: expect eof
参考源代码图片:

注意代码刚开始的第一行,指定了expect的路径,与shell脚本相同,这一句指定了程序在执行时到哪里去寻找相应的启动程序。代码刚开始还设定了timeout的时间为10秒,如果在执行scp任务时遇到了代码中没有指定的异常,则在等待10秒后该脚本的执行会自动终止。

spawn代表在本地终端执行的语句,在该语句开始执行后,expect开始捕获终端的输出信息,然后做出对应的操作。expect代码中的捕获的(yes/no)内容用于完成第一次访问目标主机时保存密钥的操作。有了这一句,scp的任务减少了中断的情况。代码结尾的expect eof与spawn对应,表示捕获终端输出信息的终止。

 

有了这段expect的代码,还只能完成对单个远程主机的scp任务。如果需要实现批量scp的任务,则需要再写一个shell脚本来调用这个expect脚本。

1: #!/bin/sh

 2: 
 3: list_file=$1
 4: src_file=$2
 5: dest_file=$3
 6: 
7: cat $list_file | while    read line
 8: do
 9:     host_ip=`echo $line | awk '{print $1}'`
 10:     username=`echo $line | awk '{print $2}'`
 11:     password=`echo $line | awk '{print $3}'`
 12:     echo "$host_ip"
 13:     ./expect_scp $host_ip $username $password $src_file $dest_file
 15: done

参考代码图片如下:

很简单的代码,指定了3个参数:列表文件的位置、本地源文件路径、远程主机目标文件路径。需要说明的是其中的列表文件指定了远程主机ip、用户名、密码,这些信息需要写成以下的格式:

IP username password

中间用空格或tab键来分隔,多台主机的信息需要写多行内容。

这样就指定了两台远程主机的信息。注意,如果远程主机密码中有“$”、“#”这类特殊字符的话,在编写列表文件时就需要在这些特殊字符前加上转义字符,否则expect在执行时会输入错误的密码。

对于这个shell脚本,保存为batch_scp.sh文件,与刚才保存的expect_scp文件和列表文件(就定义为hosts.list文件吧)放到同一目录下执行时按照以下方式输入命令就可以了:

 
 
 
 
 
 
 
 
 
 
 

1.jpg

2.jpg

3.jpg

1.jpg

2.jpg

11.jpg

12.jpg

13.jpg

14.jpg

分享到:
评论

相关推荐

    expect学习笔记及实例详解

    ### expect学习笔记及实例详解 #### 一、expect简介与基本语法 **expect** 是一个基于 **Tcl** 的程序,主要用于自动化交互式命令。它最初由 Don Libes 在 1990 年代初开发,目的是为了解决通过自动化方式与需要...

    Expect_学习笔记

    Expect 是一个基于 TCL 语言的扩展工具,专为自动化交互式应用程序设计,如 SSH、FTP 等。它能够模拟用户输入,实现自动化控制。在 Expect 中,有三个核心命令:spawn、expect 和 exp_send,它们是构建 Expect 脚本...

    expect 学习笔记

    《expect 学习笔记——自动交互的利器》 expect 是一款强大的自动化脚本工具,尤其在进行复杂的系统和网络管理任务时,它扮演着不可或缺的角色。expect 能够模拟用户与命令行界面的交互,自动处理输入和输出,极大...

    Expect笔记

    ### Expect学习笔记详解 #### 一、Expect简介 Expect 是一种基于TCL的脚本语言扩展,主要用于自动化处理那些需要用户交互的任务,如通过SSH登录远程服务器或通过FTP上传文件等场景。通过Expect,可以模拟人类操作...

    linux expect安装及expect,tcl安装包

    通过学习和使用这些资源,你不仅可以掌握如何在Linux环境中安装和使用Expect,还能了解到如何编写自动化脚本进行服务器管理,提升日常工作的效率。记得在实际操作中,安全性和权限控制都是至关重要的,确保你的自动...

    Linux expect交互命令使用详解.docx

    ### expect常用命令及参数 - `set`: 设置变量,如超时时间和自定义变量。 - `timeout`: 设置超时时间,默认10秒,`timeout -1`表示永不超时。 - `spawn`: 执行一个命令,如SSH连接。 - `expect`: 配合正则表达式,...

    RHEL 7.8安装expect及使用.docx

    RHEL 7.8 安装 expect 及使用 Expect 是一种免费的编程工具语言,用来实现自动与交互式任务进行通信,而无需人工干预。Expect 是一个用来实现自动交互功能的软件套件。系统管理员可以用它来创建脚本以实现对命令或...

    Expect and using Expect with PERL

    如果你已经熟悉Perl,那么学习Expect将会非常容易。Expect是一种基于TCL的语言,它采用了类似于Perl的语法结构(如花括号)。此外,Expect还继承了TCL的一些特性,例如强大的正则表达式处理能力。 在Expect中,最...

    shell脚本无密码登录 expect的使用方法详解

    shell脚本无密码登录 expect的使用方法详解 今天需要做一个定时任务脚本将最新的数据包文件传到远程的服务器上,虽然有密钥但也是要求输入密码的那种,所以只能另想办法实现让脚本自动输入密码了。 从网上查到使用...

    Expect 5.21 for windows

    "Expect 5.21 for Windows" 是一个专为Windows操作系统设计的自动化工具,它基于原始的Unix/Linux工具“Expect”。 Expect是一个强大的脚本语言,主要用于自动化与交互式程序的通信,例如telnet、ftp、passwd等。在...

    Expect 教程中文版

    ### Expect 教程中文版详解 #### 摘要与背景 Expect,作为一个创新的工具,旨在解决Unix环境中长久存在的问题——即如何有效地控制和自动化那些通常需要用户交互的程序。传统的Shell,如sh或csh,虽然能够启动和...

    ubuntu上expect的安装包

    在Ubuntu操作系统中,`Expect` 是一个非常有用的自动化脚本工具,它允许用户与交互式应用程序进行自动对话,比如在SSH登录、系统管理任务、自动安装软件等方面有着广泛的应用。然而,Ubuntu的默认仓库可能并未包含`...

    expect在windows下使用的

    `Expect`是一个强大的脚本工具,主要用于自动化交互式命令行程序。它的工作原理是模仿终端行为,通过发送期望的输入并捕获预期的输出来控制这些程序,尤其适合于自动登录、运行远程命令、自动化系统配置等场景。在...

    linux shell编程 Expect简介及应用中文教程

    本教程提供了一个全面的 Expect 简介和应用中文指南,包括基础语法、实例解析以及如何将 Expect 集成到你的Linux自动化工作中。通过深入学习和实践,你将能够熟练地利用 Expect 处理各种交互式任务,提高工作效率。 ...

    永远的UNIX Expect教程

    8. **实际案例**:在《永远的UNIX Expect教程中文版》中,可能会包含详细的实例,从简单的命令行程序交互到复杂的脚本设计,帮助读者逐步掌握Expect的使用。 9. **文件结构**:压缩包中的`[ 永远的UNIX Expect 教程...

    expect及其依赖rpm包(x64)

    `expect`工具正是这样一个强大的自动化脚本工具,尤其在处理交互式协议如SSH(Secure Shell)、FTP(File Transfer Protocol)和TELNET时,它能模拟用户输入,使得自动化过程变得更加简单。本文将深入探讨`expect`...

    expect5.45.3.tar.gz

    《期待与Linux世界的交互:详解expect5.45.3》 在信息技术领域,expect工具以其独特的功能在自动化脚本和系统管理中占据一席之地。expect5.45.3是一个基于TCL(Tool Command Language)语言的扩展库,它为用户提供...

    expect5.43.0和tcl8.4.11.zip

    在IT领域,`expect`和`TCL`是两种重要的脚本工具,它们在自动化任务执行、系统管理和网络通信中发挥着关键作用。`Expect`是建立在`TCL`基础上的一个扩展,专为自动交互式应用程序设计,如SSH、telnet等。` Expect...

Global site tag (gtag.js) - Google Analytics