1.expect介绍
expect 是由Don Libes基于Tcl( Tool Command Language )语言开发的,主要应用于自动化交互式操作的场景,借助Expect处理交互的命令,可以将交互过程如:ssh登录,ftp登录等写在一个脚本上,使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率
2.expect命令
expect 语法:
expect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]
选项
-c:从命令行执行expect脚本,默认expect是交互地执行的
示例:expect -c 'expect "\n" {send "pressed enter\n"} '
[root@localhost ~]# expect -c 'expect "\n" {send "pressed enter\n"}' pressed enter
-d:可以输出输出调试信息
示例:expect -d ssh.exp
expect中相关命令
spawn:启动新的进程
send:用于向进程发送字符串
expect:从进程接收字符串
interact:允许用户交互
exp_continue 匹配多个字符串在执行动作后加此命令
3.expect语法
expect最常用的语法(tcl语言:模式-动作)
单一分支模式语法:
expect "hi" {send "You said hi\n"}
匹配到hi后,会输出“you said hi”,并换行
[root@localhost ~]# expect -c 'expect "hi" {send "You said hi\n"}' hi You said hi [root@localhost html]# expect expect1.1> expect "hi" {send "You said hi\n"} hi You said hi
多分支模式语法:
expect "hi" { send "You said hi\n" } "hehe" { send "Hehe yourself\n" } "bye" { send "Good bye\n" }
[root@localhost html]# expect expect1.1> expect "hi" { send "You said hi\n" } "hehe" { send "Hehe yourself\n" } "bye" { send "Good bye\n" } hi You said hi expect1.2> expect "hi" { send "You said hi\n" } "hehe" { send "Hehe yourself\n" } "bye" { send "Good bye\n" } hehe Hehe yourself expect1.3> expect "hi" { send "You said hi\n" } "hehe" { send "Hehe yourself\n" } "bye" { send "Good bye\n" } bye Good bye
4.实例
1.自动拷贝scp
#!/usr/bin/expect spawn scp /etc/fstab wht@172.20.110.199:/home/wht/ expect { "yes/no" { send "yes\n";exp_continue } "password" { send "123456wht\n" } } expect eof
运行结果如下
[root@localhost ~]# ./scp.exp spawn scp /etc/fstab wht@172.20.110.199:/home/wht/ wht@172.20.110.199's password: fstab 100% 501 604.7KB/s 00:00
2.自动登录ssh
#!/usr/bin/expect spawn ssh 172.20.110.199 expect { "password" { send "123456wht\n" } } interact #登录成功后,会保持登录的状态不会主动退出 #expect eof
运行结果如下
[root@localhost ~]#./ssh.exp spawn ssh 172.20.110.199 root@172.20.110.199's password: Last login: Sat May 12 11:23:54 2018 from 172.20.110.169 [root@localhost ~]#
3.变量
#!/usr/bin/expect set ip 172.20.110.199 set user root set password 123456wht set timeout 10 spawn ssh $ip expect { "password" { send "$password\n" } } interact #expect eof
运行结果如下
[root@localhost ~]#./sshbl.exp spawn ssh 172.20.110.199 root@172.20.110.199's password: Last login: Sat May 12 11:26:45 2018 from 172.20.110.169 [root@localhost ~]#
4.位置参数
#!/usr/bin/expect set ip [lindex $argv 0] set user [lindex $argv 1] set password [lindex $argv 2] spawn ssh $user@$ip expect { "yes/no" { send "yes\n";exp_continue } "password" { send "$password\n" } } interact #./ssh3.exp 192.168.8.100 root magedu
5.执行多个命令
示例
#!/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 test\n" } expect "]#" { send "echo magedu |passwd --stdin test\n" } send "exit\n" expect eof #./ssh4.exp 172.20.110.199 root 123456wht
6.shell脚本调用expect
自动在多台主机创建用户test,并设置初始口令
1.expect 自动在多台主机创建用户test,并设置初始口令
#!/bin/bash #expect 自动在多台主机创建用户test,并设置初始口令(读取文件) ssdzd(){ expect <<-EOF set timeout 10 spawn ssh $user@$ip expect { "yes/no" { send "yes\n";exp_continue } "password" { send "$password\n" } } expect "]#" { send "useradd test\n" } expect "]#" { send "echo 123456thw |passwd --stdin test\n" } expect "]#" { send "exit\n" } expect eof EOF } a=`cat /root/passwd|wc -l` echo $a for i in `seq $a` ; do echo $i ip=`cat /root/passwd|head -n $i|tail -n 1|cut -d : -f 1` user=`cat /root/passwd|head -n $i|tail -n 1|cut -d : -f 2` password=`cat /root/passwd|head -n $i|tail -n 1|cut -d : -f 3` ssdzd done
运行结果如下
[root@localhost ~]#bash ssh3.sh spawn ssh root@172.20.110.199 root@172.20.110.199's password: Last login: Sat May 12 15:02:16 2018 from 172.20.110.169 [root@localhost ~]# useradd test useradd: warning: the home directory already exists. Not copying any file from skel directory into it. Creating mailbox file: File exists [root@localhost ~]# echo 123456thw |passwd --stdin test Changing password for user test. passwd: all authentication tokens updated successfully. [root@localhost ~]# exit logout Connection to 172.20.110.199 closed. spawn ssh root@172.20.108.143 root@172.20.108.143's password: Last login: Fri May 4 13:09:37 2018 from 172.20.110.169 echo -e "\e[1;31mhi dangerous\e[0m" [root@localhost ~]# useradd test useradd: warning: the home directory already exists. Not copying any file from skel directory into it. Creating mailbox file: File exists [root@localhost ~]# echo 123456thw |passwd --stdin test Changing password for user test. passwd: all authentication tokens updated successfully. [root@localhost ~]# exit logout Connection to 172.20.108.143 closed.
2.expect 自动在多台主机创建用户test,并设置初始口令
#!/bin/bash #自动在多台主机创建用户test,并设置初始口令(脚本文件写入user,ip,password) ssdzd(){ expect <<-EOF set timeout 10 spawn ssh $user@$ip expect { "yes/no" { send "yes\n";exp_continue } "password" { send "$password\n" } } expect "]#" { send "useradd test1\n" } expect "]#" { send "echo 123456thw |passwd --stdin test1\n" } expect "]#" { send "exit\n" } expect eof EOF } cat >> /root/passwd.txt << EOF 172.20.110.199:root:123456wht 172.20.108.143:root:123456wht EOF DIR=/root/passwd.txt a=`cat $DIR|wc -l` for i in `seq $a` ; do ip=`cat $DIR|head -n $i|tail -n 1|cut -d : -f 1` user=`cat $DIR|head -n $i|tail -n 1|cut -d : -f 2` password=`cat $DIR|head -n $i|tail -n 1|cut -d : -f 3` ssdzd done >$DIR
运行结果如下
[root@localhost ~]#bash ssh4.sh spawn ssh root@172.20.110.199 root@172.20.110.199's password: Last login: Sat May 12 15:16:46 2018 from 172.20.110.169 [root@localhost ~]# useradd test1 useradd: user 'test1' already exists [root@localhost ~]# echo 123456thw |passwd --stdin test1 Changing password for user test1. passwd: all authentication tokens updated successfully. [root@localhost ~]# exit logout Connection to 172.20.110.199 closed. spawn ssh root@172.20.108.143 root@172.20.108.143's password: Last login: Fri May 4 13:24:03 2018 from 172.20.110.169 echo -e "\e[1;31mhi dangerous\e[0m" [root@localhost ~]# useradd test1 useradd: user 'test1' already exists [root@localhost ~]# echo 123456thw |passwd --stdin test1 Changing password for user test1. passwd: all authentication tokens updated successfully. [root@localhost ~]# exit logout Connection to 172.20.108.143 closed.
批量ssh-copy-id
#!/bin/bash #用于批量ssh-copy-id 免密码登陆服务器 which expect || yum -y install expect TXT_PATH=/home/wht/ssh-login/list.txt ssdzd(){ expect <<-EOF set timeout 10 spawn ssh-copy-id $user@$ip expect { "yes/no" { send "yes\n";exp_continue } "password" { send "$password\n" } } expect "]#" { send "exit\n" } expect eof EOF } a=`cat ${TXT_PATH}|wc -l` echo $a for i in `seq $a` ; do echo $i ip=`cat ${TXT_PATH}|head -n $i|tail -n 1|awk '{print $1}'` user=`cat ${TXT_PATH}|head -n $i|tail -n 1|awk '{print $2}'` password=`cat ${TXT_PATH}|head -n $i|tail -n 1|awk '{print $3}'` ssdzd done
list.txt
192.168.8.27 root zmoam#11232134 192.168.8.31 root zmoam#11231234
没有帐号? 立即注册