1) 获取命令行参数,例如通过./abc.exp a1 a2执行expect脚本

set 变量名1 [lindex $argv 0] 获取第1个参数a1

set 变量名2 [lindex $argv 1] 获取第2个参数a2

2)函数中使用外部变量

例如在函数外部定义了变量va:  set va "", 现在现在某个函数中使用,需要通过全局范围限定符进行引用,即$::va,如果进行变量修改,可以使用 set ::va xxx

3) 在expect中执行shell语句

例如:

exec sh -c {

if [ -f "$HOME/.ssh/known_hosts" ]
then
    >$HOME/.ssh/known_hosts
fi
}

4) 获取spawn id

例如:

spawn ssh -l $::LAB_USER $IP
set MY_SPAWN_ID $spawn_id

5)  expect以及send指定spawn id

如果只是简单的一个spawn远端连接,随后进行expect/send语句,无需指定spawn id, 有时比较复杂,比如有多个spawn id,那么需要使用 -i 指明具体哪一个,例如:

expect {
        -i $::MY_SPAWN_ID
        "/home/xxx:" {
            send -i $::MY_SPAWN_ID "YOUR SHELL CMD HERE\r";
        }
        timeout { puts "timeout for xxx"; exit }
    }

6) 获取send命令执行结果

可以通过$expect_out(buffer) 获取上一次send命令以后的远端输出结果,此变量必须在send以后的下一个expect { }语句中使用才有效。上一个send最好也是在某个expect{ }中执行,否则可能不起作用。例如:

expect {
        "#" {
            send  "ps -ef|grep my_app|grep -v grep\r"; (grep -v表示取反,去掉不想要的信息,因为会有一条多余的grep命令在grep结果中显示出来)
        }
        timeout { puts "timeout for xxx"; exit }
    }
expect {
        "#" {
            puts "Got response: $expect_out(buffer)";
        }
        timeout { puts "timeout for xxx"; exit }
    }

7) 清空expect_out结果

在expect { }语句内部执行unset expect_out(buffer);

8) 正则匹配

例如:

expect {

-i $::MY_SPAWN_ID
        "#" {
            send  -i  $::MY_SPAWN_ID "ps -ef|grep my_app|grep -v grep\r";  
        }
        timeout { puts "timeout for xxx"; exit }
    }

假设执行send语句以后的远端输出如下:

root      4608  3351  0 13:45 ?        00:00:06 my_app --io 393228

root      5490  3351  2 13:46 ?        00:00:18 my_app --io 360459

现在先获取最后一列的393228与360459,那么可以通过以下正则获取:

(注意,下面代码里的中括号【和】需要使用英文的中括号 [ 和 ],这里用中文是因为CSDN会把英文转义搞错,仅仅为了显示)

expect {
        -i $::MY_SPAWN_ID
        -re "(my_app --io\\s+)(\【0-9\】+)" {
            puts "Got my_app process: $expect_out(2,string)";  (此时会输出393228,如果是$expect_out(0,string)那么将输出my_app --io 393228)
            unset expect_out(buffer);
        }
        timeout { puts "timeout for KEEP_1_PROCESS"; exit }
    }
    expect {
        -i $::MY_SPAWN_ID
        -re "(my_app --io\\s+)(\【0-9\】+)" {
            puts "Got my_app process: $expect_out(2,string)"; (此时会输出360459)
            send -i $::MY_SPAWN_ID "\r\n";
        }
        timeout { puts "No more $:APP found, continue" }
    }

其中可以将正则表达式用括号进行分组,从而获取想要的字段,比如上面用了两个括号组织,通过$expect_out(2,string)可以获取想要的字段。

不管用不用括号分组,都可以通过$expect_out(0,string)获得完全匹配的output

9) 发送Ctrl-C
如果想向远端发送Ctrl-C结束远端进程,可以通过send "\003" 实现。

10) expect/shell互相使用彼此变量
如果是在shell中启动了expect脚本,现在想在expect中使用shell里的变量,可以有两种方法:
首先在shell中进行变量export, 例如export a=1, 然后在expect中通过 $::env(a) 引用,例如set a_exp $::env(a)
也可以通过执行子shell调用,例如: set a [exec sh -c {echo $a}]

如果是在expect里面执行shell,并且想在shell里面使用expect的变量,需要在expect里面设置环境变量:

例如:set ::env(LAB) my_lab

那么在shell语句里面可以通过$LAB引用。

11) 写入文件操作
首先打开文件流,然后写入内容,最后关闭文件流

set tmp_file [open $::TMP_OUT a+]

expect {
... ...
puts $tmp_file $expect_out(buffer);
unset expect_out(buffer)
}
expect {
... ...
puts $tmp_file $expect_out(buffer);
unset expect_out(buffer)
}

close $tmp_file

12) expect 交互或者退出
如果是交互,那么执行interact 或者加上-i spawn的id
如果是结束,那么执行send "exit\r"以后 expect eof,此时会等待expect进程结束。
如果想快速退出而不等待,那么可以在执行完send "exit\r"以后wait -nowait 立即退出。

13) 获取当前时间
set current_time [clock format [clock seconds] -format "%Y-%m-%d,%H:%M:%S"]

14) scp 文件传输

比如:

spawn scp $YOUR_LOGIN@$YOUR_SERVER:$FILE .

expect {
    "password:" {
        gets stdin PASSWD

send "$PASSWD\r"

puts "This may take a while, please wait ......"

}
    timeout { puts "timeout for login "; exit }
}
expect {
    "No such file or directory" {
        puts "The file $FILE not exists, please have a check"
        exit
    }

}

expect eof

传输一个大文件,脚本最后通过expect eof由于expect eof的超时时间很短,默认10秒,因此很可能导致文件传输不完整,解决方法是:将expect eof改成 expect -timeout -1 eof
————————————————
版权声明:本文为CSDN博主「taoyuanforrest」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/just_lion/article/details/80109764

expect使用技巧的更多相关文章

  1. 10 个 Redis 建议/技巧

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/145.html?1455790611 Redis 在当前的技术社区里是非常 ...

  2. (译)开发优秀的虚拟现实体验:从开发I Expect You to Die中总结的六个要点

    这篇文章是我从网上找来的,我觉得他非常详细的解释了VR发展的需求和必要.我认为通过这篇文章可以让大家了解VR. 译者写在最前: 来到追光动画有好几个月了,抱歉这段时间也没有什么文章与大家分享,我现在在 ...

  3. jQuery常用技巧-使用的总结

    1.关于页面元素的引用 通过jquery的$()引用元素包括通过id.class.元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用do ...

  4. 关于Python ,requests的小技巧

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/xie_0723/article/details/52790786 关于 Python Request ...

  5. google搜索小技巧

    google搜索小技巧 一.总结 一句话总结:But most people may not be using Google search to its full potential.Want to ...

  6. 【技巧总结】Penetration Test Engineer[3]-Web-Security(SQL注入、XXS、代码注入、命令执行、变量覆盖、XSS)

    3.Web安全基础 3.1.HTTP协议 1)TCP/IP协议-HTTP 应用层:HTTP.FTP.TELNET.DNS.POP3 传输层:TCP.UDP 网络层:IP.ICMP.ARP 2)常用方法 ...

  7. 自动交互式脚本--expect

    我们经常会遇到一些需要与服务器程序打交道的场景,比如,从登陆某个服务器,然后进行某项工作.这很平常,但是如果把这个工作自动化进行,你就需要一个程序能自动做你要告诉机器的事情,这样,我们的expect就 ...

  8. jQuery常用技巧

      1.关于页面元素的引用 通过jquery的$()引用元素包括通过id.class.元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用 ...

  9. Python Requests 小技巧总结

    关于 Python Requests ,在使用中,总结了一些小技巧把,分享下. 1:保持请求之间的Cookies,我们可以这样做. import requests self.session = req ...

随机推荐

  1. caffe的python接口学习(5)生成deploy文件

    如果要把训练好的模型拿来测试新的图片,那必须得要一个deploy.prototxt文件,这个文件实际上和test.prototxt文件差不多,只是头尾不相同而也.deploy文件没有第一层数据输入层, ...

  2. C++中i++和++i的区别

    目录 效果上的区别 性能上的区别 分析汇编代码 进行性能实验 二者的选择 效果上的区别 i++是对变量i递增,但返回原值,++i是对变量i进行递增,并返回终值. 可以用以下代码加以验证: int i ...

  3. Java使用IO流读取TXT文件

    通过BufferedReader读取TXT文件window系统默认的编码是GBK,而IDE的编码多数为UTF-8,如果没有规定new InputStreamReader(new FileInputSt ...

  4. JavaScript基础函数的属性:记忆模式(019)

    函数在Javascript里是有属性的,因为它们是一种特殊对象.事实上,就算是没有明确声明,函数在最初就已经包含了一些固有的属性,比如所有函数都length这个属性,它可以指出函数声明了多少个参数: ...

  5. 深度学习论文翻译解析(八):Rich feature hierarchies for accurate object detection and semantic segmentation

    论文标题:Rich feature hierarchies for accurate object detection and semantic segmentation 标题翻译:丰富的特征层次结构 ...

  6. 《算法笔记》6.7小节 问题 A: 简单计算器

    又是大模拟淦淦淦淦淦淦淦 思路: 这道题我居然用的队列orz. 言归正传,这道题就是模拟计算器.从读题目样例可以发现,数字的个数只比符号的个数多一个,那么这就给我们了思路:用队列,先提前放出一个数,每 ...

  7. 十.总结drf视图

     一.对一个资源的五个操作: 如users资源: 序列化是把模型/表中数据以json格式的数据返回给前端,反序列化是把前端通过http post提交过来的json格式数据(data)插入到数据库. 小 ...

  8. Mybatis架构相关的知识

    如上所示,这是一个简单的Mybaits执行流程. 我们其实可以看到,一直到第三步(Sqlsession)那么一步,这都是我们的程序里需要创建的.而之后的步骤才是底层完成的任务. 这里就有了一个引申的概 ...

  9. css定位方式有哪几种?

    复杂的网页布局都是通过各种网页元素灵活定位实现的,网页中的各种元素定位都有自己的特点.下面我们来看一下css的几种定位方式. float定位(即浮动定位): 这种定位方式很简单,只需规定一个浮动的方向 ...

  10. C++中cin>>a原理

    int a; vector<int>res; while(cin>>a){ res.push_back(a); } 给出这段代码 可以输入1 2  3 4 5并以回车结束,从而 ...