1. Shell脚本实现自动登录
#!/usr/bin/expect -f
set IP 115.22.33.44
set PASSWORD pwdpwd
spawn ssh root@$IP
expect {
"*yes/no" { send "yes\r" }
"*password:" { send "$PASSWORD\r" }
}
interact #交互模式,用户会停留在远程服务器上面
复制代码
其中,*password:"是一种模糊匹配:如果终端输出了以"password:"的交互窗口,脚本就自动匹配并执行{send "$PASSWORD\r"}中的内容。\r表示回车执行。
2. 自动登录后执行命令
比如说,登录服务器后要执行一个导出mysql数据库的命令。
首先,在变量部分增加如下内容:
#!/usr/bin/expect -f
set IP 115.22.33.44
set PASSWORD pwdpwd
set DB_HOST localhost
set DB_USER dbuser
set DB_PASS mysqlpwd
set DB_NAME dbname
set SERVER_PATH /root/www
spawn ssh root@$IP
expect {
"*yes/no" { send "yes\r" }
"*password:" { send "$PASSWORD\r" }
}
expect "root@*" {send "cd $SERVER_PATH\r"}
expect "root@*" {send "mysqldump -u$DB_USER -p$DB_PASS -h$DB_HOST -B $DB_NAME > $DB_NAME.sql\r"
expect eof
复制代码
3、在expect脚本中使用bash
值得注意的是,上述脚本都引用了#!/usr/bin/expect -f,可以称之为expect脚本。expect和bash是两回事,内部使用的语法也就完全不同了。
有时在expect脚本需要继续执行一些bash,该怎么做呢?比如上面将数据库导出后,下载到本地,导入本地数据库,则需要使用 spawn bash。
#!/usr/bin/expect -f
set IP 115.22.33.44
set USER root
set PASSWORD pwdpwd
set DB_HOST localhost
set DB_USER dbuser
set DB_PASS mysqlpwd
set DB_NAME dbname
set SERVER_PATH /root/www
set LOCAL_PATH /Users/Download
set LOCAL_DB_USER root
set LOCAL_DB_PASS localdbpwd
set prompt {\$ $}
spawn ssh $USER@$IP
expect {
"*yes/no" { send "yes\r" }
"*password:" { send "$PASSWORD\r" }
}
#使用puts而不是echo,来输出信息
puts "login to server: $IP and dump database $DB_NAME"
expect "root@*" {send "cd $SERVER_PATH\r"}
expect "root@*" {send "mysqldump -u$DB_USER -p$DB_PASS -h$DB_HOST -B $DB_NAME > $DB_NAME.sql\r"
expect eof
puts "下载 $DB_NAME.sql 到本地"
spawn scp $USER@$IP:$SERVER_PATH/$DB_NAME.sql $LOCAL_PATH/
expect {
"*yes/no" { send "yes\r" }
"*password:" { send "$PASSWORD\r" }
}
expect eof
puts "导入本地mysql数据库"
spawn /bin/bash
expect -re $prompt
send "cd $LOCAL_PATH\r"
send "mysql -u$LOCAL_DB_USER -p$LOCAL_DB_PASS -e'drop database if exists $DB_NAME;source $TEMP_PATH/$DB_NAME.sql;'\r"
send "exit\r"
expect eof
exit复制代码