zoukankan      html  css  js  c++  java
  • expect使用技巧


    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 ";
            }
            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 "; (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 ";  
            }
            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 " ";
            }
            timeout { puts "No more $:APP found, continue" }
        }

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

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

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

    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 "以后 expect eof,此时会等待expect进程结束。
    如果想快速退出而不等待,那么可以在执行完send "exit "以后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 "

            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

  • 相关阅读:
    [J2ME Q&A]MMAPI的Cannot parse this type of AMR异常之讨论
    FM91.5的EasyMorning节目爱听吗?
    [EntLibFAQ]“不允许所请求的注册表访问权”的解释[0508Update]
    亮出你的组合竞争力的王牌
    隔离,隔离,再隔离!
    zuma三阶段论和技术道路[一]
    分享下我们部门内部知识点培训教程[SIP/J2ME/Setup/LoadRunner/Domino][0706Up]
    [Remoting FAQ]Loading a Remoting Host On IIS得到BadImageFormatException
    通过讲课来建立自己的知识系统
    j2medev“用户界面和多媒体”版面问题整理[0407更新]
  • 原文地址:https://www.cnblogs.com/lgj8/p/12296442.html
Copyright © 2011-2022 走看看