expect不完全使用指南

expect介绍

expect是一个自动交互功能的工具。expect命令会新建一个子进程,通过spawn来执行shell脚本,监测脚本的返回结果,然后通过expect判断要进行的交互输入内容。

借助Expect处理交互的命令,可以将交互 过程如:ssh登录,ftp登录等写在一个脚本上,使之自动化完成.尤其适用于需 要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率 。

expect安装

Expect是一个基于TCL开发出的语言包。系统一般不会自带,需要自行安装。

TCL(Tool Command Language)工具脚本语言,是Linux内的一种语言包。

系统为RHEL/CentOS:

yum install expect

系统为Debian/Ubuntu:

apt-get install expect

expect脚本

expect脚本以#!/usr/bin/expect开头,用来告诉操作系统脚本里的代码使用那一个shell来执行。这里的expectlinux下的bashwindows下的cmd是一类东西。

以.exp或者.ex结束,通过./xxx.exp运行(需要可执行权限),类似bash脚本。

也可以以sh结尾,通过expect ./xx.sh执行,如expect ./auto_deploy.sh

expect 命令选项

​expect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ] 

​ 选项

  • -v:显示expect版本信息。

  • -f:从文件读取命令,仅用于使用#!时。如果文件名为file,则从stdin读取(使用./file从文件名为file的文件读取)。

  • -c:从命令行执行expect脚本,默认expect是交互地执行的,如下所示:

    expect -c 'expect "\n" {send "pressed enter\n"}
    

    如果你执行了上面的脚本,它会等待输入换行符\n。按enter键以后,它会打印出pressed enter这个消息,然后退出。

  • -i:使用-i选项,可以通过来自于标准输入的读命令来交互地执行expect脚本。如下所示:

    expect -i arg1 arg2 arg3
    expect1.1>set argv
    arg1 arg2 arg3
    expect1.2>
    

    正常情况下,当你执行上面的expect命令的时候(没有-i选项),它会把arg1当成脚本的文件名,所以-i选项可以让脚本把多个参数当成一个连续的列表。

  • -d:可以输出输出调试信息

    $ cat sample.exp
    # !/usr/bin/expect -f
    expect “\n”;
    send “pressed enter”;
    
    $ expect -d sample.exp
    expect version 5.43.0
    argv[0] = expect argv[1] = -d argv[2] = sample.exp
    set argc 0
    set argv0 “sample.exp”
    set argv “”
    executing commands from command file sample.exp
    
    expect: does “” (spawn_id exp0) match glob pattern “\n”? no
    
    expect: does “\n” (spawn_id exp0) match glob pattern “\n”? yes
    expect: set expect_out(0,string) “\n”
    expect: set expect_out(spawn_id) “exp0”
    expect: set expect_out(buffer) “\n”
    send: sending “pressed enter” to { exp0 pressed enter}
    
  • -b: 通常,expect会在执行脚本之前,把整个脚本都读入到内存中。-b选项可以让expect一次只读取脚本中的一行。当你没有写完整个脚本的时候,这是十分有用的,expect可以开始执行这个不完整的脚本。

    expect -b
    
  • -d:让expect不解释命令行参数

    你可以使用标识符让expect不解释命令行参数。你可以像下面这样的读入命令行参数:

    $ cat print_cmdline_args.exp
    #!/usr/bin/expect
    puts ‘argv0 : [lindex $argv 0];
    puts ‘argv1 : [lindex $argv 1];
    

    当执行上面的脚本的时候,会跳过命令行选项,它们会被当成参数(而不是expect选项),如下所示:

    $ expect print_cmdline_args.exp -d -c
    argv0 : -d
    argv1 : -c
    

expect内置命令

  • set timeout: 设置超时时间的,单位是:秒 。例如:set timeout 30

    # 永远等待,不会超时
    set timeout -1  
    
  • spawnspawn是进入expect环境后才可以执行的expect内部命令,如果没有装expect或者直接在默认的SHELL下执行是找不到spawn命令的。所以不要用 which spawn之类的命令去找spawn命令。spawn用来启动新的进程的,spawn后的sendexpect命令都是和spawn打开的进程进行交互的。

    # 直接运行一个 bash 脚本
    spawn /mnt/sh_expect.sh
    # 直接运行一个 bash 命令
    spawn ssh -p ${port} $user@$host
    
  • send:用于向进程发送命令字符串 ,这里就是执行交互动作,与手工输入的动作等效。 命令字符串结尾别忘记加上\n

  • expectexpect也是expect的一个内部命令,expectshell命令和内部命令是一样的,但不是一个功能。这个命令的意思是判断上次输出结果里是否包含指定的字符串,如果有则立即返回,否则就等待一段时间后返回,这里等待时长就是set timeout xxx 设置的时间。

    # 从标准输入中等到hi和换行键后,向标准输出输出hello there
    expect "hi\n"
    send "hello there!\n"
    # 退出 spawn 会话,返回当前的shell进程
    send "exit\n"
    # 退出expect
    expect eof
    
  • interact:从自动交互状态退出到输入状态,由用户完成剩余的操作.,这个时候就可以手工操作了。如果没有这一句登录完成后会退出,而不是留在远程终端上。

  • exp_continue:重置set timeout设置的时间,重新执行当前expect分支

    # 如果匹配到*assword,那么发送密码,并进入下面的expect语句(uname -a语句)。
    # 如果匹配到yes/no,那么发送yes,并重新执行这个expect分支语句。
    expect {
        "*assword" {send "123456\r";}
        "yes/no" {send "yes\r";exp_continue}
    }  
    

命令行参数

$argc$argv 0,$argv 1 ... $argv n  

argc表示命令行参数个数,后面分别表示各个参数项,0表示第一个参数,1表示第二个参数,以此类推,可以通过lindex获取对应参数值[lrange $argv 0 0]

if {$argc < 2} {
	puts stdout "$argv0 err params\n"
	exit 1
}
set user [lindex $argv 0]
set password [lindex $argv 1]

参数存在argv 当中,[lrange $argv 0 0]表示第1个参数,[lrange $argv 0 4]为第一个到第五个参数。如果需要计算的话必须用expr,如计算2-1,则必须用[expr 2-1]

语法

expect遵循tcl的语法规范,基础语法部分可以查看这里,循环、条件判断、各种运算符都有详细的说明

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值