初识Expect工具
功能说明
expect 是由Don Libes基于 Tcl( Tool Command Language )语言开发的,主要应用于自动化交互式 操作的场景,借助 expect 处理交互的命令,可以将交互过程如:ssh登录,ftp登录等写在一个脚本 上,使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人 员的工作效率
expect语法
expect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]
常见选项
-c:从命令行执行expect脚本,默认expect是交互地执行的
-d:可以调试信息
expect中的相关命令
expect中相关命令
spawn 启动新的进程
expect 从进程接收字符串
send 用于向进程发送字符串
interact 允许用户交互
exp_continue 匹配多个字符串在执行动作后加此命令
单独expect的使用
[ root@Ansible-Master ~15:47]
expect1.1 > set timeout -1
-1
expect1.2 > expect "hi" { send "you said hi\n " }
xxx hhhh iiii hi
you said hi
expect1.1 > expect {
+> "hi" { send "You said hi\n " }
+> "hehe" { send "Hehe yourself\n " }
+> "bye" { send " Good bye\n " }
+> }
bye
Good bye
expect脚本
#!/usr/bin/expect
spawn scp /etc/redhat-release 192.168 .213.122:/data
expect {
"yes/no" { send "yes\n " ; exp_continue }
"password" { send "redhat\n " }
}
expect eof
spawn ssh 10.0 .0.7
expect {
"yes/no" { send "yes\n " ; exp_continue }
"password" { send "redhat\n " }
}
interact
expect变量
#!/usr/bin/expect
set ip 10.0 .0.7
set user root
set password redhat
set timeout 10
spawn ssh $user @$ip
expect {
"yes/no" { send "yes\n " ; exp_continue }
"password" { send "$password \n " }
}
interact
expect 位置参数
#!/usr/bin/expect
set ip [ lindex $argv 0 ]
set user [ lindex $argv 1 ]
set password [ lindex $argv 2 ]
set timeout 10
spawn ssh $user @$ip
expect {
"yes/no" { send "yes\n " ; exp_continue }
"password" { send "$password \n " }
}
expect "]#" { send "useradd xiang\n " }
expect "]#" { send "echo redhat |passwd --stdin xiang\n " }
send "exit\n "
expect eof
./expect-2 192.168 .213.121 root redhat
shell调用expect
#!/bin/bash
IP = $1
user = root
password = redhat
log_file = /root/expect.log
/usr/bin/expect << EOF
set timeout -1
spawn ssh ${user} @${IP}
expect {
"yes/no" { send "yes\n ";exp_continue }
"password" { send "${password} \n " }
}
expect "]$" { send "id xiang\n " }
expect "]$" { send "echo redhat | passwd --stdin xiang\n " }
expect "]$" { send "exit\n " }
expect eof
EOF
shell调用expect并记录日志
#!/bin/bash
IP = $1
user = root
password = redhat
log_file = /root/expect.log
/usr/bin/expect <<- EOF
logfile expect.log
set timeout -1
spawn ssh ${user} @${IP}
expect {
"yes/no" { send "yes\n ";exp_continue }
"password" { send "${password} \n " }
}
expect "]$" { send "id xiang\n " }
expect "]$" { send "echo redhat | passwd --stdin xiang\n " }
expect "]$" { send "exit\n " }
expect eof
EOF
usr/bin/expect << EOF > /root/expect.log
logfile expect.log
set timeout -1
spawn ssh ${user} @${IP}
expect {
"yes/no" { send "yes\n ";exp_continue }
"password" { send "${password} \n " }
}
expect "]$" { send "id xiang\n " }
expect "]$" { send "echo redhat | passwd --stdin xiang\n " }
expect "]$" { send "exit\n " }
expect eof
EOF
范例
file_log = "/root/expect.log"
color_green = "echo -e \033 [1;32m"
color_red = "echo -e \033 [1;31m"
color_end = "\033 [0m"
for file in /etc/yum.repos.d/*.repo ; do
if [ ! -e ${file} ] ; then
${color_red} "请配置epel源" ${color_end} ; exit 1
fi
done
grep 'epel' /etc/yum.repos.d/*.repo && { yum makecache || { ${color_red} "yum不可用" ${color_end} ; exit 1 ; } } || { echo "epel未配置" ; exit 1 ; }
${color_green} "install expect rsync start...." ${color_end}
yum -y -q install expect rsync expect > /dev/null || ${color_red} "package install failure " ${color_end}
db_type = ` rpm -qa | grep -E 'mysql|mariadb' | awk -F"-" '{if(NR == 1)print $1}' `
if [ [ $db_type =~ mariadb ] ] ; then
systemctl stop $db_type
else
db_type = "mysqld"
systemctl stop mysqld
fi
read -p "mysql-backup the IPaddres:" mysql_backup
read -s -p "mysql-backup the password:" Password_1
read -p "mysql-master the IPaddres:" mysql_master
read -s -p "mysql-master the password:" Password
/usr/bin/expect << EOF
set timeout 20
spawn ssh-keygen
expect {
"Enter" { send "\n ";exp_continue }
"Enter" { send "\n "}
"Enter" { send "\n "}
}
expect eof
EOF
/usr/bin/expect << EOF
set timeout 20
spawn scp /root/.ssh/id_rsa.pub ${mysql_backup} :/root/.ssh
expect {
"password" { send "${Password_1} \n " }
}
expect eof
EOF
/usr/bin/expect << EOF > ${file_log}
set timeout 20
spawn ssh root@${mysql_backup}
expect {
"yes/no" { send "yes\n ";exp_continue }
"password" { send "${Password_1} \n " }
}
expect "#" { send "mkdir -p /backup/mysql-backup/\n " }
expect "#" { send "cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys\n " }
expect "#" { send "yum -y -q install rsync opensll >/dev/null \n " }
expect "#" { send "ssh-keygen -t rsa -f /root/sshkey -q\n " }
expect "passphrase" { send "\n " }
expect "Enter" { send "\n " }
expect "#" { send "scp /root/sshkey.pub ${mysql_master} :/root\n " }
expect "password" { send "${Password} \n " }
expect "#" { send "exit\n " }
expect eof
EOF
if [ -e /root/sshkey.pub ] ; then
cat /root/sshkey.pub | tee /root/.ssh/authorized_keys
rsync -a /etc/my.cnf ${mysql_backup} :/backup/mysql-backup/
rsync -a /etc/my.cnf.d ${mysql_backup} :/backup/mysql-backup/
rsync -a /var/lib/mysql ${mysql_backup} :/backup/mysql-backup/
else
echo "backup failure" ; exit 1
fi
systemctl start $db_type