Chinaunix首页 | 论坛 | 博客
  • 博客访问: 407928
  • 博文数量: 403
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: -70
  • 用 户 组: 普通用户
  • 注册时间: 2016-09-05 12:45
文章分类

全部博文(403)

文章存档

2014年(3)

2013年(1)

2012年(3)

2011年(21)

2010年(13)

2009年(64)

2008年(9)

2007年(36)

2006年(253)

分类: LINUX

2011-05-24 08:56:32

利用expect实现自动交互

by  ( )

题纪:

    作为喻信服务器的管理员,前几天要实现一个定时更新mysql数据库的脚本,本来

用crond这个守护进程很好实现,只要编辑/var/spool/cron/root,在里面加入一行:

00 2 *  *  *(cd /usr/local/mysql/data; ./quotaget.sh; mysql -p < update.sql)

也即是在每天凌晨2:00自动更新数据库。关于crontab的语法可以参考:

 

但是遇到了一个问题,即执行mysql -p < update.sql这条语句时,需要用户输入密码。

尽管shell功能很强大,但对于需要用户输入密码的程序,shell并不能非交互的运行,

于是上网搜索到了expect这个工具,用了才知道这个工具对于一个系统管理员来说是多

么的有价值。

 

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

   (Expect is a software suite for automating interactive tools。

    Expect的官方主页对它作了如下介绍:
    Expect is a tool for automating interactive applications such as telnet,
    ftp, passwd, fsck, rlogin, tip, etc. Expect really makes this stuff
    trivial. Expect is also useful for testing these same applications. And
    by adding Tk, you can also wrap interactive applications in X11 GUIs.

    Expect是基于TCL的,作为一个脚本语言,expect能在无需管理员参与的情况下实现

自动交互(比如passwd,fsck,telnet等),expect也能用于自动测试一些应用程序。

    expect的语法和shell的语法非常相似,它支持函数调用,有while语句,switch

语句。

1)    expect使用spawn调用其他的执行程序,比如

    spawn  telnet  218.199.20.98  2600

    但是在使用的过程中发现spawn不支持管道和重定向,也就是说对于

        ls |more ; mysql -p < update.sql 这样的命令spawn不能正确解析。

    解决的办法是把这些命令放到一个shell脚本里面,在用spawn执行这个shell

    脚本。

2)    expect 创建子函数使用proc标志,也即:

    proc  functionname { parameter1,parameter2 } {
       ……

    }

    调用子函数非常简单

    functionname  $param1 $param2

3)  expect  使用expect ,send 组合实现自动交互 ,语法如下:

    expect {
            "login;"  {  send  "$user\n"   }
            "passwd:" {  send  "$passwd\n" }

    }
    使用send的使用后面的内容不显示给用户,如要显示给用户,应使用send_user

4) 注意点:

   1. expect里面基本是都是使用{} 而不是使用(),比如函数参数输入外面应用{},

应该是while { } 而不是 while ( ).

   2. { 应和其他符合有空格, expect { 正确,expect{ 就会报错.

   3.  spawn 不支持管道和重定向.

5) 下面是实现的mysql数据库自动更新的expect脚本:

   proc do_console_login {pass} {

        set timeout 5

    set done 1

    while { $done } {
                expect {
                          "password:" {
                               send "$pass\n"
                          }
                          eof {
                                set done 0
                          }
                }
    }
   }

   if {$argc<1} {

        puts stderr "Usage: $argv0  password.\n "
        exit 1
   }

   set PASS    [lindex $argv 0]

   spawn   /usr/local/mysql/data/updatemysql

   do_console_login  $PASS

阅读(1016) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~