expect用法及举例
2013-06-21通过Shell可以实现简单的控制流功能。但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如telnet/ftp/ssh服务器等进行交互的功能。而Expect就使用来实现这种功能的工具。
Expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。Expect的作者Don Libes在1990年开始编写Expect时,对Expect做有如下定义:Expect是一个用来实现自动交互功能的软件套件 (Expect [is a] software suite for automating interactive tools)。
Expect的工作方式象一个通用化的Chat脚本工具。Chat脚本最早用于UUCP网络内,以用来实现计算机之间需要建立连接时进行特定的登录会话的自动化。
Chat脚本由一系列expect-send对组成:expect等待输出中输出特定的字符,通常是一个提示符,然后发送特定的响应。
例1:ssh.sh实现ssh无密码登陆
#!/bin/sh
ip=$1
password=abcdefg
if [ -z "$1" ];then
echo Usage: $0 ip
exit 1;
fi
set timeout 30
spawn ssh -l root $ip -p322
expect "password:"
send "${password}\r"
interact
例2:rsa.sh实现自动交互执行ssh-keygen
#/bin/sh
username=$1
if [ -z "$1" ];then
echo Usage: $0 username
exit 1;
fi
echo "please input ssh-keygen passphrase"
read $password
su - ${username} -c "/usr/bin/expect" << EOF
spawn ssh-keygen -t rsa
expect "Enter"
send "\n"
expect "y\n"
send "y\r"
expect "Enter passphrase"
send "$password\r"
expect "Enter same passphrase again"
send "$password\r"
expect EOF
exit
EOF
more ~/.ssh/id_rsa.pub
spawn后 send 最后都追加一个回车符\r。因为这是程序之间的交互,用的是回车。
但是没有spawn的情况下,send后面追加的是\n。这是方便输出到终端的操作。
例3:ftp-rfc获取rfc
#!/bin/sh
# \
exec expect -- "$0" ${1+"$@"}
# ftp-rfc
# ftp-rfc -index
# retrieves an rfc (or the index) from uunet
exp_version -exit 5.0
if {$argc!=1} {
send_user "usage: ftp-rfc \[#] \[-index]\n"
exit
}
set file "rfc$argv.Z"
set timeout 60
spawn ftp ftp.uu.net
expect "Name*:"
send "anonymous\r"
expect "Password:"
send "expect@nist.gov\r"
expect "ftp>"
send "binary\r"
expect "ftp>"
send "cd inet/rfc\r"
expect "550*ftp>" exit "250*ftp>"
send "get $file\r"
expect "550*ftp>" exit "200*226*ftp>"
close
wait
send_user "\nuncompressing file - wait...\n"
exec uncompress $file
参考
http://linux.chinaitlab.com/c/809655.html
http://sourceforge.net/projects/expect/