linux expect脚本详解

linux脚本 waitig 5029℃ 百度已收录 0评论

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

基本介绍

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

Expect是一个用来实现自动交互功能的软件套件(Expect [is a] software suite for automating interactive tools)。

Expect语言是基于Tcl的, 作为一种脚本语言,Tcl具有简单的语法:    

cmd arg arg arg

一条Tcl命令由空格分割的单词组成. 其中, 第一个单词是命令名称, 其余的是命令参数 .

$foo

$符号代表变量的值. 在本例中, 变量名称是foo.

[cmd arg]

方括号执行了一个嵌套命令. 例如, 如果你想传递一个命令的结果作为另外一个命令的参数, 那么你使用这个符号 .

“some stuff”

双引号把词组标记为命令的一个参数. “$”符号和方括号在双引号内仍被解释。

大括号也把词组标记为命令的一个参数. 但是, 其他符号在大括号内不被解释。

反斜线符号() 是用来引用特殊符号. 例如:n 代表换行. 反斜线符号也被用来关闭”$”符号 , 引号,方括号和大括号的特殊含义 .

用法简介

本文用一个最短的例子来介绍下其最基本的使用语法:

例子

##############################################
#!/usr/bin/expect
set timeout 30
spawn ssh -l username 192.168.1.1
expect "password:"
send "ispass/r"
interact
##############################################

1. [#!/usr/bin/expect]
  这一行告诉操作系统脚本里的代码使用那一个shell来执行。这里的expect其实和linux下的bash、windows下的cmd是一类东西。
  注意:这一行需要在脚本的第一行。
  2. [set timeout 30]
  基本上认识英文的都知道这是设置超时时间的,现在你只要记住他的计时单位是:秒
  3. [spawn ssh -l username 192.168.1.1]
spawn是进入expect环境后才可以执行的expect内部命令,如果没有装expect或者直接在默认的SHELL下执行是找不到spawn命令的。所以不要用 “which spawn“之类的命令去找spawn命令。好比windows里的dir就是一个内部命令,这个命令由shell自带,你无法找到一个dir.com 或 dir.exe 的可执行文件。
  它主要的功能是给ssh运行进程加个壳,用来传递交互指令。
  4. [expect “password:”]
  这里的expect也是expect的一个内部命令,有点晕吧,expect的shell命令和内部命令是一样的,但不是一个功能,习惯就好了。这个命令的意思是判断上次输出结果里是否包含“password:”的字符串,如果有则立即返回,否则就等待一段时间后返回,这里等待时长就是前面设置的30 秒
  5. [send “ispass/r”]
  这里就是执行交互动作,与手工输入密码的动作等效。
  温馨提示: 命令字符串结尾别忘记加上“/r”,如果出现异常等待的状态可以核查一下。
  6. [interact]
  执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了。如果没有这一句登录完成后会退出,而不是留在远程终端上。如果你只是登录过去执行

举例详解

下面我们就使用一个例子来详细介绍下其语法及使用:

proc do_console_login {login pass} {
    set timeout 5
    set done 1
    set timeout_case 0
    while ($done) {
          expect {
                "console login:" { send "$loginn" }
                "Password:" { send "$passn" }
                "#" {
                    set done 0
                    send_user "nnLogin Successfully...nn"
                }
                timeout {
                    switch -- $timeout_case {
                          0 { send "n" }
                          1 {
                                send_user "Send a return...n"
                                send "n"
                          }
                          2 {
                                puts stderr "Login time out...n"
                                exit 1
                          }
                    }
                    incr timeout_case
                }
          }
    }
}
proc do_exec_cmd {} {
    set timeout 5
    send "n"
    expect "#"
    send "uname -pn"
    expect "#"
    send "ifconfig -an"
    expect "#"
    send "exitn"
    expect "login:"
    send_user "nnFinished...nn"
}
if {$argc<2} {

    puts stderr "Usage: $argv0 login passwaord.n "
    exit 1
}
set LOGIN   [lindex $argv 0]
set PASS   [lindex $argv 1]
spawn telnet 10.13.32.30 7001
do_console_login $LOGIN $PASS
do_exec_cmd
close
exit 0

    上面的脚本只是一个示例,实际工作中,只需要重新实现do_exec_cmd函数就可以解决类似问题了。
    在例1中,还可以学习到以下Tcl的语法:

1. 命令行参数
        $argc,$argv 0,$argv 1 … $argv n
        if {$argc<2} {
            puts stderr “Usage: $argv0 login passwaord.n “
            exit 1
        }

2. 输入输出
        puts stderr “Usage: $argv0 login passwaord.n “

3. 嵌套命令
        set LOGIN   [lindex $argv 0]
        set PASS   [lindex $argv 1]

4. 命令调用
        spawn telnet 10.13.32.30 7001

5. 函数定义和调用
        proc do_console_login {login pass} {
            …………..        
        }

6. 变量赋值
        set done 1

7. 循环.

        while ($done) {
            …………….
        }

8. 条件分支Switch
        switch — $timeout_case {
            0 {
              ……………
            }
            1 {
              ……………        

            }
            2 {
              ……………     
            }
        }

9. 运算

incr timeout_case

此外,可以加-d参数来调试脚本

# /usr/bin/expect -d sample_login.exp root 111111


本文由【waitig】发表在等英博客
本文固定链接:linux expect脚本详解
欢迎关注本站官方公众号,每日都有干货分享!
等英博客官方公众号
点赞 (3)分享 (0)