用Expect实现命令行交互的自动化操作

From: http://www.hiadmin.com

Expect 是一个控制交互式程序的工具。你可以用它来编写一段脚本来处理一些交互式的操作,比如执行passwd、su 远程登录 ssh,远程命令操作等 ,如果你有多台服务器需要执行相同的操作命令,用Expect就比较适合。
下面这段文字描述了expect的一些概念。
* Expect 是一种特定的、高级的和通用的编程语言,其语法与 Tcl 相同,并增加了 Tcl 中所没有的一些特殊用途的命令。
    * Expect 是一种可执行程序,从它正确地处理用 Expect 语言编写的输入的角度来看,它实现了这种语言。
    * expect 命令是其中的一个命令,Expect 以此对 Tcl 进行了扩展。
    * Expect 是一个 Tcl 包。一般说来,这意味着任何 Tcl 应用程序都可以在运行时加载 Expect 功能。
    * Expect 是一个基于 C 源代码的库,而这些 C 源代码则深入到 Expect 可加载的包和 Expect 可执行程序。
    * Expect 是某种工具的抽象概念,该工具:
          o 实现终端交互的自动化,甚至在涉及到密码或者其他特殊项目的情况下
          o 实现了一种“对话”模型,通过它对消息和响应的简单规律进行编码

下面两篇文章详细介绍了Expect的使用
http://fanqiang.chinaunix.net/a4/b8/20010912/1000001278.html
http://www.ibm.com/developerworks/cn/aix/library/au-expect/index.html

当然,在学习Expect 之前你应当先学习一些Tcl编程的内容,请看这里 TclTk中文网,另外expect 的安装需要依赖Tcl,你必须首先安装 Tcl。

下面是我写的一段演示脚本,主要操作是从一个文本中批量读取ip地址,普通用户用户名和密码,超级用户密码,执行ssh登录,su root 操作 然后退出

pwd.txt
127.0.0.1       mars    1234        root            123456
192.168.0.3       mars    1234        root            123456

run.exp
#!/usr/bin/expect
set timeout 5
proc do_ssh_login {host username pass susername spass} {
    set timeout_case 0
    set done 1
 
    send_user "\n"
    spawn ssh $username@$host
    send_user "正在连接主机 $host\n"
    while {$done} {
 
     expect {
             timeout {
                  switch -- $timeout_case {
                 0 { send "\n" }
                 1 {
                      send_user "重试...\n"
                      send "\n"
                   }
                 2 {
                     puts stderr "登录超时...\n"
             close
             set done 0
             break
                   }
               }
               incr timeout_case
              }
 
        "*(yes/no)?" {send "yes\n"}      
        "?assword:"  {send "$pass\n"}
        "*Permission denied*" {    send_user "登录受限\n"
                    close
                    set done 0
                    break
                      }
           "*Connection refused*" { send_user "主机不可访问\n"
                    close
                    set done 0
                    break
                       }
        "*$*" {send_user "\n登录成功...\n"
            if {[string  equal $susername "NULL"] !=1} {
                    send "export LC_ALL=en_US\r"
                    send "su - $susername\r"
                       expect "*Password:*"
                       sleep 1
                       send "$spass\n"
                expect {
                    "*Authentication failure*" {send_user "密码错误\n"
                                        close
                                    break
                                           }
                           "*Permission denied*" {send_user "登录受限\n"
                                       close
                                   break
                                           }  
                        }
            }
              }
        "*#*" {
                send_user  "超级用户登录成功\n"
                send_user "\n*************************$host********************************\n"
                send "cat /proc/cpuinfo |grep model\\ name\n"
                expect "#"
                send "df -T\n"
                expect "#"
                send "fdisk -l\n"
                expect "#"
                send "free\n"
                expect "#"
                send "lspci\n"
                expect "#"
                expect {
                "#" {set done 0
                     send_user "\n***************************************************************\n"
                     send_user "\n"
                     send "exit\n"
                   }
                }
          }
        }
    }
 
}
 
set f [open "pwd.txt" r]
while { [gets $f line] >= 0 } {
set su [lindex $line 3]
set sp [lindex $line 4]
if { [string length $su] <=0 } {
    set sp "NULL"
    set su "NULL"
}
do_ssh_login [lindex $line 0] [lindex $line 1] [lindex $line 2]  $su $sp
}
 
close $f

 » 相关连接:
Linux SHELL if 命令参数说明 Shell扩展 引用字符 变量
Bash环境 Bash独有的特性 Shell特性 捕捉信号
变量进阶 shift内建命令 使用select内建命令来制作菜单 I/0 重定向和循环
 » 本栏目最新帖:

Powered by PHPWind v6.0 Code © 2003-08