shell中的expect语句

expect

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

参数含义及说明

  • spawn 是 expect 中的监控程序,其运行后会监控命令提出的交互问题
  • send,发送问题答案给交互命令
  • “\r”,表示回车
  • exp_continue,表示当问题不存在时继续回答下面的问题
  • expect eof ,表示问题回答完毕退出 expect 环境
  • interact,表示问题回答完毕留在交互界面
  • set NAME [ lindex $argv n ],定义变量
  • set timeout -1 设置超时方式为永远等待
  • set timeout 30 设置超时时间为30秒
  • [lindex $argv 0] 获取expect脚本的第1个参数
  • [lindex $argv 1] 获取expect脚本的第2个参数

expect 示例

  • 不用expect的情况:
    写一个问问题脚本:vim ask.sh
read -p "What's your name:" NAME
read -p "How old are you:" AGE
read -p "Which object you study:" OBJ
read -p "Are you happy:" FEEL
echo $NAME is $AGE\'s old study $OBJ feel $FEEL

脚本的执行需要我们一一给出答案:
shell中的expect语句_第1张图片现在我们写一个有问题的答案的脚本,在我们执行该脚本时会自己把答案输入重定向到文问题的脚本中。

vim answer.sh

sh /mnt/ask.sh <<-EOF
zhang
20
management
happy
EOF

在这里插入图片描述但是当我们将问问题的脚本中注释掉一个问题时,再执行回答的脚本,就会出现错乱。
shell中的expect语句_第2张图片在这里插入图片描述

  • 使用expect的情况:
    安装expect
yum install expect -y
vim answer.exp    编写文件
#!/bin/cat
/mnt

chmod +x answer.exp

在这里插入图片描述

vim answer.exp
aaa
aaa
aaa
aaa

shell中的expect语句_第3张图片
可以看到这样执行脚本中的内容都是显示出来
分开写回答

vim answer.exp

spawn sh /mnt/ask.sh
expect "name"
send "zhang\r"
expect "old"
send "20\r"
expect "object"
send "management\r"
expect "happy"
send "happy\r"
expect eof

或 interact

执行 ./answer.exp
shell中的expect语句_第4张图片
写到一起:

#!/usr/bin/expect
set NAME [ lindex $argv 0 ]
set AGE [ lindex $argv 1 ]
set OBJ [ lindex $argv 2 ]
set FEEL [ lindex $argv 3]
spawn sh /mnt/ask.sh
expect {
        "name" { send "$NAME\r" ; exp_continue }
        "old" { send "$AGE\r" ; exp_continue }
        "object" { send "$OBJ\r" ; exp_continue }
        "happy" { send "$FEEL\r" }
}
expect of

执行
shell中的expect语句_第5张图片

练习题

知道某一主机的密码,要求用ssh连接这台主机

vim ssh.exp

#!/usr/bin/expect
set IP [ lindex $argv 0 ]
set PASSWD [ lindex $argv 1 ]
spawn ssh root@$IP
expect {
        "yes/no" { send "yes\r" ; exp_continue }
        "password" { send "$PASSWD\r" }
}
interact

chmod +x ssh.exp

测试:expect ssh.exp 172.25.254.10 redhat
shell中的expect语句_第6张图片

练习题

编写脚本显示1-10台主机里开着的主机名
思路:首先看他开着没,然后hostname显示主机名

vim hostname.sh

#!/bin/bash
Auto_SSH()    写一个函数
{
/usr/bin/expect <<-EOF
spawn ssh root@$1 hostname                    ##对齐写,将这些东西输入定向到expect的环境中运行
expect {
"yes/no" { send "yes\r" ; exp_continue }        
"password" { send "redhat\r" }                ##前面的是提取的关键字,后面发送的是答案
}
expect eof
EOF
}

for IP in {1..10}
do
        ping -c1 -w1 172.25.254.$IP &> /dev/null
        if [ "$?" = "0" ]
        then
        Auto_SSH 172.25.254.$IP | tail -n 1
        fi
done

注意:
$1脚本后的第一串字符
$IP带入函数的第一串字符
执行结果:
在这里插入图片描述

跟我们写:
lftp 172.25.254.10  << EOF
> cd /pub
> get xxx
> EOF
的道理一样
把这些命令放到lftp的环境中运行

你可能感兴趣的:(shell)