expect脚本使用说明解释


expect详解和N个示例

expect 说明

首先,expect并不是系统自带的命令,需要安装tcl和expect命令,有外网的直接yum即可,没有外网的 参考:https://blog.csdn.net/cuichongxin/article/details/101275878
执行expect脚本方法: expect 脚本名

expect选项

  • -c:执行脚本前先执行的命令,可多次使用。
  • -d:debug模式,可以在运行时输出一些诊断信息,与在脚本开始处使用exp_internal 1相似。
  • -D:启用交换调式器,可设一整数参数。
  • -f:从文件读取命令,仅用于使用#!时。如果文件名为"-",则从stdin读取(使用"./-"从文件名为-的文件读取)。
  • -i:交互式输入命令,使用"exit"或"EOF"退出输入状态。
  • –:标示选项结束(如果你需要传递与expect选项相似的参数给脚本时),可放到#!行:#!/usr/bin/expect --。
  • -v:显示expect版本信息。

命令(参数)说明

  • set:可以设置超时,也可以设置变量
  • timeout:expect超时等待时间,默认10S
  • timeout -1:永不超时退出
  • spawn:执行一个命令
  • expect “”:匹配输出的内容
  • exp_continue [-continue_timer]:继续执行下面匹配
  • send “”:用于向进程发送字符串
  • interact:允许用户交互,交互后不退出远程终端,如果加要把expect “root@*” {send “exit\r”}注释掉,如果不加,就直接退出
  • \t:空格
  • \n:换行(echo –e “\n” 查看效果)
  • \r:可以理解为回车
  • $argc:统计位置参数数量
  • [lindex $argv 0]:脚本后第一个参数,类似于shell中$1,以此类推
  • puts “”:打印字符串,类似于echo
  • awk -v I="$ip":赋值变量
  • expect{…}:输入多行记录

示例

1 打印内容测试

expect中打印命令是puts,类似于echo,但我用send也可以打印,并且2样并看不出明显区别,不知道结合其他情况使用会不会有冲突啥的,按需使用吧。

#expect "this"
send "this is my test\n"
#interact
send "\n"
puts "thisis my plustest"

在这里插入图片描述

2 查看远程主机磁盘分区(set定义变量)

#!/usr/bin/expect

set ip 目标ip
set pass 目标ip的root密码   
set timeout 30 #设置30秒超时退出,可不要
spawn ssh root@$ip
expect {  
        "(yes/no)" {send "yes\r"; exp_continue}# 这里是用于第一次登陆读取输入yes或no的,不是第一次登陆 可不要
        "password:" {send "$pass\r"} # password是获取内容关键字,获取到后send替代手工输入密码
}
expect "root@*"  {send "df -h\r"} # root是获取关键字,[root@control ~]$ 
expect "root@*"  {send "exit\r"} # 退出
expect eof # 结束,如果不加 可能send命令无法全部执行
# interact  # 按需要决定是否添加interact

在这里插入图片描述

3 查看远程主机磁盘分区(不用set定义变量)

这是最简单直接的,我平常执行多条命令都喜欢用这种方法,但这种实用于执行多条命令,如果只执行一条命令,这不是最简单的,执行一条命令3是最简单的

spawn ssh 目标ip
expect {
        "(yes/no)" {send "yes\r"; exp_continue}
        "password:" {send "目标iproot的密码\r"}
}
expect "root@*"  {send "df -h\r"}
expect "root@*"  {send "exit\r"}
expect eof

在这里插入图片描述

4 查看远程主机磁盘分区(单条命令最简单方法)

#!/bin/expect

spawn ssh ip df -h
expect {
        "(yes/no)" {send "yes\r"; exp_continue}
        "password:" {send "root的密码\r"}
}
expect eof

spawn ssh ip df -h
expect {
        "(yes/no)" {send "yes\r"; exp_continue}
        "password:" {send "root的密码\r"}
}
expect eof

在这里插入图片描述

5 自动ssh 登陆会话(无interact介入)

这儿的自动的意思是,接受用户输入的用户名,ip,密码,命令

#!/usr/bin/expect -f

# 接收第1个参数,作为IP
set ip [lindex $argv 0 ]      
# 接收第2个参数,作为username
set username [lindex $argv 1 ] 
# 接收第3个参数,作为密码
set mypassword [lindex $argv 2 ] 
# 接收第4个参数,作为命令
# 还可以设置第5,第100个参数用来作为命令
set mycommand [lindex $argv 3 ] 
# 设置超时时间,可以不要
set timeout 10 
 
# 向远程服务器请求打开一个ssh会话,并等待服务器询问用户名
spawn ssh $username@$ip
    # 等待匹配输入密码界面(如果免密的可不要这步,要也不影响)
    expect "password:"
    # 输入密码,并等待键入需要运行的命令
    send "$mypassword\r"
    #"*@*" 是获取关键字[root@control ~]
    expect "*@*"
    # 输入预先定好的密码,等待运行结果
    send "$mycommand\r"
    expect "*%*"
    # 可以将命令运行结果写到磁盘中
    send "$mycommand >> /tmp/test.a\r"
    # 退出telnet会话,等待服务器的退出提示EOF(没提示退出以前,不要人为输入)
    send "exit\r"
expect eof

在这里插入图片描述

运行方式以及结果(缺陷 只能只有没有参数的命令,带参数的用不了,比如:df –h),如果要执行多条命令,可以稍微改一下,使用用户介入的方式,见demo6
在这里插入图片描述
最重要的是能实现这种形式,使用环境 按需使用吧。

6 自动ssh登陆(interact介入)

interact介入简单理解为 交换模式吧,就是说自动 登陆进去以后就停留在登陆的服务器上,可以自由输入命令然后 exit 退出! 不过没啥用,写这么写命令 就为了登陆,还不如直接 ssh 上去来的痛快。 反正当 只是为了知道interact的作用把!

#!/usr/bin/expect -f

# 接收第1个参数,作为IP
set ip [lindex $argv 0 ]      
# 接收第2个参数,作为username
set username [lindex $argv 1 ] 
# 接收第3个参数,作为密码
set mypassword [lindex $argv 2 ] 
# 设置超时时间,可以不要
set timeout 10 
 
# 向远程服务器请求打开一个ssh会话,并等待服务器询问用户名
spawn ssh $username@$ip
    # 等待匹配输入密码界面(如果免密的可不要这步,要也不影响)
    expect "password:"
    # 输入密码,并等待键入需要运行的命令
    send "$mypassword\r"
    # interact 介入,手动输入命令。。。
    interact

在这里插入图片描述

7 openstack快速一次性查看

spawn ssh ip
#expect {
 #       "~assword" { send "root\r";}  
  #      "yes/no" {send "yes\r"exp_continue} 
#} 
# 上面4行我注释的原因是 该服务器是免密登陆的,为例节约运行时间 所以我注释掉了。
expect "~]#" {send " source openrc\r"} 
expect "~]#" {send "openstack compute service list\r"} 
expect "~]#" {send "ceph -s\r"} 
expect "~]#" {send "ssh 0.0.0.0 ceph -s\r"} 
expect "~]#" {send "ssh 0.0.0.0 ceph -s\r"} 
expect "~]#" {send "systemctl is-active rabbitmq-server.service\r"}
expect "~]#" {send "ssh 0.0.0.0 systemctl is-active rabbitmq-server.service\r"} 
expect "~]#" {send "ssh 0.0.0.0systemctl is-active rabbitmq-server.service\r"} 
send "exit\r" 
expect eof

在这里插入图片描述

expect嵌入到shell中

平常我们使用expect脚本方式是 expect 脚本名,但我们可以把expect脚本嵌入到 shell中,这样就可以执行 sh 脚本名,然后shell中调用expect脚本即可
在这里插入图片描述

发布了98 篇原创文章 · 获赞 66 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/cuichongxin/article/details/105248035
今日推荐