shell编程之expect用法
2018-05-13 15:46:42    6107    0    0
wang2020

    

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





上一篇: 二.mysql介绍和存储引擎

下一篇: shell编程之函数

6107 人读过
立即登录, 发表评论.
没有帐号? 立即注册
0 条评论
文档导航