【shell】expect命令详解:用expect实现自动化交互式操作

一. 运用场景

expect主要应用于自动化交互式操作的场景,借助Expect处理交互的命令,可以将交互过程如:ssh登录,ftp登录等写在一个脚本上,使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率。

二. 语法说明

注意:该脚本能够执行的前提是安装了expect

yum install -y expect

在使用expect时,有以下几个常见的命令:
在这里插入图片描述

说明:
spawn

用来启动新的进程,spawn后的expect和send命令都是和使用spawn启动的新进程进行交互。
spawn是expect的初始命令,用于启动一个进程,之后所有操作都在这个进程中进行,如果没有spawn,这个expect都无法进行。

 
expect

用来等待一个进程的反馈,我们根据进程的反馈,再使用send命令发送对应的交互命令。

 
send

接收一个字符串参数,并将该参数发送到进程。

 
interact

用的其实不是很多,interact命令主要用于退出自动化,进入人工交互。
比如我们使用spawn、send和expect命令完成了ftp登陆主机,执行下载文件任务,但是我们希望在文件下载结束以后,仍然可以停留在ftp命令行状态,以便手动的执行后续命令,此时使用interact命令就可以很好的完成这个任务。

三. 例子

1. scp文件传输自动化

使用scp 命令的时候如果是第一次通讯需要通过交互的方式手工按yes之后才能进入第二步,然后手工输入密码才能进行文件传输。

#!/usr/bin/expect -d

set timeout 10
spawn -noecho ssh -o StrictHostKeyChecking=no -l test 192.168.2.151 -p 22
#spawn命令是expect的初始命令,他用于启动一个进程,之后所有操作都在这个进程中进行,
#如果没有spawn,这个expect都无法进行
#StrictHostKeyChecking=no参数让ssh默认添加新主机的公钥指纹,也就不会出现出现是否继续yes/no的提示了

expect "password:" {
    
    send "123456\r"}
expect "Last login" {
    
    send "echo test1\r"}
expect "*\$*" {
    
    send "echo test2\r"}
expect eof

# EOF(End Of File),表示"文字流"(stream)的结尾。这里的"文字流",可以是文件(file),
# 也可以是标准输入(stdin),EOF是不可输出字符,因此不能在屏幕上显示。
# 由于字符的ASCII码不可能出现-1,因此EOF定义为-1是合适的。
#即当读入的字符值等于EOF时,表示读入的已不是正常的字符而是文件结束符。

2. ssh远程登录

#!/bin/bash

passwd='123456'

/usr/bin/expect <<-EOF

# exp_continue 用于多次匹配
set time 30
spawn ssh saneri@192.168.56.103 df -Th
expect {
    
    
"*yes/no" {
    
     send "yes\r"; exp_continue }
"*password:" {
    
     send "$passwd\r" }
}
expect eof
EOF

3. 切到root用户

#!/usr/bin/expect -f

set timeout 10

spawn sudo su - root
expect "*password*"
send "123456\r"
expect "#*"
send "ls\r"
expect "#*"
send "df -Th\r"
send "exit\r"
expect eof

4. 创建ssh key

1.创建主机配置文件

[root@localhost script]# cat host 
192.168.1.10 root 123456
192.168.1.20 root 123456
192.168.1.30 root 123456




2.编写copykey.sh脚本,自动生成密钥并分发key.

#!/bin/bash
# 判断id_rsa密钥文件是否存在
if [ ! -f ~/.ssh/id_rsa ];then
 ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
else
 echo "id_rsa has created ..."
fi

#分发到各个节点,这里分发到host文件中的主机中.
while read line
  do
    user=`echo $line | cut -d " " -f 2`
    ip=`echo $line | cut -d " " -f 1`
    passwd=`echo $line | cut -d " " -f 3`
    
    expect <<EOF
      set timeout 10
      spawn ssh-copy-id $user@$ip
      expect {
    
    
        "yes/no" {
    
     send "yes\n";exp_continue }
        "password" {
    
     send "$passwd\n" }
      }
     expect "password" {
    
     send "$passwd\n" }
EOF
  done <  hosts

5. ssh到一个节点创建用户

#!/bin/bash 
ip=$1  
user=$2 
password=$3 

expect <<EOF  
    set timeout 10 
    spawn ssh $user@$ip 
    expect {
    
     
        "yes/no" {
    
     send "yes\n";exp_continue } 
        "password" {
    
     send "$password\n" }
    } 
    expect "]#" {
    
     send "useradd hehe\n" } 
    expect "]#" {
    
     send "touch /tmp/test.txt\n" } 
    expect "]#" {
    
     send "exit\n" } expect eof 
 EOF  
 
 
 #./ssh5.sh 192.168.1.10 root 123456

 
 
参考:
https://www.cnblogs.com/saneri/p/10819348.html
https://blog.csdn.net/givenchy_yzl/article/details/118079170
https://sites.google.com/site/chinainventor/language/2009-04-03-02

猜你喜欢

转载自blog.csdn.net/hiliang521/article/details/131447176