Expect是交互性很强的脚本语言,可以帮助运维人员实现批量管理成千上百台服务器操作,是一款很实用的批量部署工具!Expect依赖于tcl,而linux系统里一般不自带安装tcl,所以需要手动安装。下面记录下Expect的安装部署及使用过程:
1. 安装部署Expect
下载:expect-5.43.0.tar和tcl8.4.11-src.tar 下载地址:https://pan.baidu.com/s/1kVyeLt9 提取密码:af9p 将expect和tcl的软件包下载放到/usr/local/src目录下 1)解压tcl,进入tcl解压目录,然后进入unix目录进行编译安装 [root@xw4 src]# tar -zvxf tcl8.4.11-src.tar.gz [root@xw4 src]# cd tcl8.4.11/unix [root@xw4 unix]# ./configure [root@xw4 unix]# make && make install 2)安装expect [root@xw4 src]# tar -zvxf expect-5.43.0.tar.gz [root@xw4 src]# cd expect-5.43.0 [root@xw4 expect-5.43.0]# ./configure --with-tclinclude=/usr/local/src/tcl8.4.11/generic --with-tclconfig=/usr/local/lib/ [root@xw4 expect-5.43.0]# make && make install 3)安装完成后进行测试 [root@xw4 ~]# expect expect1.1> expect1.1>
2. Expect使用示例1
从本机自动登录到远程机器192.168.1.200(端口是22,密码是:PASSWORD),登录到远程机器后做以下几个操作: 1. useradd wangshibo 2. mkdir /opt/test 3. exit自动退出 1) 脚本内容如下 [root@xw4 tmp]# cat test-ssh.sh #!/bin/bash passwd='PASSWORD' /usr/local/bin/expect <<-EOF set time 30 spawn ssh -p22 root@192.168.1.201 expect { "*yes/no" { send "yes\r"; exp_continue } "*password:" { send "$passwd\r" } } expect "*#" send "useradd wangshibo\r" expect "*#" send "mkdir /opt/test\r" expect "*#" send "exit\r" interact expect eof EOF 执行脚本, 发现登录到远程主机192.168.1.201后确实自动执行了上面三个操作: [root@xw4 tmp]# chmod 755 test.sh [root@xw4 tmp]# sh test.sh spawn ssh -p22 root@192.168.1.201 root@192.168.1.201's password: Last login: Fri Sep 23 16:21:20 2016 from 192.168.1.23 [root@vm-002 ~]# useradd wangshibo [root@vm-002 ~]# mkdir /opt/test [root@xw4 tmp]# ########################################################################### 上面示例如果只是想实现自动登陆目的,登陆机器后不做操作。则脚本只需改成下面即可: [root@xw4 tmp]# cat test.sh [root@xw4 tmp]# cat test.sh #!/bin/bash passwd='PASSWORD' /usr/local/bin/expect <<-EOF set time 30 spawn ssh -p22 root@192.168.1.201 expect { "*yes/no" { send "yes\r"; exp_continue } "*password:" { send "$passwd\r" } } expect eof EOF 执行脚本: [root@xw4 tmp]# sh test.sh [root@xw4 tmp]# sh test.sh spawn ssh -p22 root@192.168.1.201 root@192.168.1.201's password: Last login: Fri Sep 23 16:21:20 2016 from 192.168.1.23 [root@vm-002 ~]# ########################################################## 如上示例只实现自动登录目的,如果使用expect脚本,则写法如下: [root@xw4 tmp]# cat test #!/bin/expect set timeout 30 spawn ssh -p22 root@192.168.1.201 expect "*password:" send "PASSWORD\r" interact 执行脚本: [root@xw4 tmp]# chmod 755 test [root@xw4 tmp]#./test ########################### 需要注意: spawn后面跟的是操作动作,比如登陆机器后执行uptime,即: # spawn ssh -p22 root@192.168.1.201 "uptime"
2. Expect使用示例2
在部署无密码访问时, 手工建立ssh互信需要好几个步骤,并且中途人工交互(输入密码等),如果机器数目多,则很繁琐!下面方法用于自动化生成authorized_keys, 免去了手工操作。具体思路:利用expect编写sshkey.exp在远程主机上生成id_rsa,并重定向到本地;在利用noscp.exp.把文件复制到远程主机。
1)查看expect安装后的路径是: [root@xw4 ~]# which expect /usr/local/bin/expect 2)做个expect执行文件的软件 [root@xw4 ~]# ln -s /usr/local/bin/expect /usr/bin/expect [root@xw4 ~]# ll /usr/bin/expect 3)编写expect脚本:sshkey.exp和noscp.exp [root@xw4 ~]# cat sshkey.exp #!/usr/bin/expect #sshkey.exp if {$argc<3} { puts stderr "Usage: $argv0 host user passwd " exit 1 } set host [ lindex $argv 0 ] set user [ lindex $argv 1 ] set pwd [ lindex $argv 2 ] set timeout 30 #spawn ssh ${user}@${host} "rm -rf ~/.ssh/id_rsa*" # #expect { # "*yes/no" { send "yes\r"; exp_continue } # "*password:" { send "$pwd\r"; exp_continue } #} spawn ssh ${user}@${host} "ssh-keygen -t rsa" #如果ssh端口是非22,比如22222,那么这一行的ssh后面添加"-p22222" expect { "*yes/no" { send "yes\r"; exp_continue } "*password:" { send "$pwd\r"; exp_continue } "Enter file in which to save the key*" { send "\n\r"; exp_continue } "Overwrite*" { send "y\n"; exp_continue } "Enter passphrase (empty for no passphrase):" { send "\n\r"; exp_continue } "Enter same passphrase again:" { send "\n\r" } } spawn ssh ${user}@${host} "cat ~/.ssh/id_rsa.pub" #如果ssh端口是非22,比如22222,那么这一行的ssh后面添加"-p22222" expect { "*yes/no" { send "yes\r"; exp_continue } "*password:" { send "$pwd\r" } } expect eof ############################################################# [root@xw4 ~]# cat noscp.exp #!/usr/bin/expect #noscp.exp if {$argc<4} { puts stderr "Usage: $argv0 localfile remotefile user passwd " exit 1 } set localfile [ lindex $argv 0 ] set remotefile [ lindex $argv 1 ] set user [ lindex $argv 2 ] set pwd [ lindex $argv 3 ] set timeout 30 spawn scp ${localfile} ${user}@${remotefile} #如果ssh端口是非22,那么这一行里面的scp后面添加"-P 22222" expect { "*yes/no" { send "yes\r"; exp_continue } "*password:" { send "$pwd\r" } } expect eof 4)对上面两个脚本授执行权限 [root@xw4 ~]# chmod 755 sshkey.exp [root@xw4 ~]# chmod 755 noscp.exp 这两个脚本文件用法: # ./sshkey.exp 主机名 用户名 密码 #在远程主机生成id_rsa # ./noscp.exp 本地文件 远程路径 远程用户密码 #无密码拷贝文件 5)验证 [root@xw4 ~]# ./sshkey.exp 192.168.1.201 root PASSWORD |grep ssh-rsa >> ~/.ssh/authorized_keys [root@xw4 ~]# ./noscp.exp ~/.ssh/authorized_keys 192.168.1.201:~/.ssh root PASSWORD spawn scp /root/.ssh/authorized_keys root@192.168.1.201:~/.ssh root@192.168.1.201's password: authorized_keys 这样,就能无密码登陆了! [root@xw4 ~]# ssh 192.168.1.201 Last login: Fri Sep 23 18:33:21 2016 from 192.168.1.7 [root@vm-002 ~]#
######## 上面示例2中,如果是多台机器的话,可以结合shell脚本进行批量执行 ########
[root@xw4 ~]# cat /root/ip.list 192.168.1.100 192.168.1.101 192.168.1.102 192.168.1.103 192.168.1.104 ...... ...... [root@xw4 ~]# cat sshkey.sh #!/bin/bash for ip in `cat /root/ip.list` do /root/sshkey.exp $ip root PASSWORD |grep ssh-rsa >> ~/.ssh/authorized_keys /root/noscp.exp ~/.ssh/authorized_keys $ip:~/.ssh root PASSWORD done [root@xw4 ~]# sh -x sshkey.sh
######## 贴一个简单的expect跳转脚本 ########
localhost:huan kevin$ cat jump #!/usr/bin/expect set timeout 30 spawn /usr/bin/ssh -p 2200 -l wangshibo 111.133.132.144 expect "password:" send "shai3raesh2Uici\r" interact localhost:huan kevin$ ./jump spawn /usr/bin/ssh -p 2200 -l wangshibo 111.133.132.144 wangshibo@111.133.132.144's password: Last login: Fri Oct 13 16:43:13 2017 from 210.12.101.146 Welcome to aliyun Elastic Compute Service! [wangshibo@sh-sre-man01 ~]$