学会云计算运维Expect免交互一篇就够了!!!

一: Shell Here Document(内嵌文档/嵌入文档)

Shell 还有一种特殊形式的重定向叫做“Here Document”,目前没有统一的翻译,你可以将它理解为“嵌入文档”“内嵌文档”“立即文档”。
所谓文档,就是命令需要处理的数据或者字符串;所谓嵌入,就是把数据和代码放在一起,而不是分开存放(比如将数据放在一个单独的文件中)。有时候命令需要处理的数据量很小,将它放在一个单独的文件中有点“大动干戈”,不如直接放在代码中来得方便。

1.1:Here Document 的基本用法为:

command <<END
  document
END

command是 Shell 命令,<<END是开始标志,END是结束标志,document是输入的文档(也就是一行一行的字符串)。

这种写法告诉 Shell 把 document 部分作为命令需要处理的数据,直到遇见终止符END为止(终止符END不会被读取)。

注意,终止符END必须独占一行,并且要定顶格写。

分界符(终止符)可以是任意的字符串,由用户自己定义,比如 END、MARKER 等。分界符可以出现在正常的数据流中,只要它不是顶格写的独立的一行,就不会被作为结束标志。

1.2:注意事项

标记可以使用任意合法字符

结尾的标记一定要顶格写,前面不能有任何字符!!

结尾的标记后面也不能有任何字符(包括空格)

开头标记前后的空格会被省略掉

【实例1】cat 命令一般是从文件中读取内容,并将内容输出到显示器上,借助 Here Document,cat 命令可以从键盘上读取内容。

[root@server1 ~]#  cat <<END
> Shell教程
> http://c.biancheng.net/shell/
> 已经进行了四次改版
> END
Shell教程
http://c.biancheng.net/shell/
已经进行了四次改版

<是第二层命令提示符。

正文中也可以出现结束标志END,只要它不是独立的一行,并且不顶格写,就没问题。

[mozhiyan@localhost ~]$ cat <<END
> END可以出现在行首
> 出现在行尾的END
> 出现在中间的END也是允许的
> END
END可以出现在行首
出现在行尾的END
出现在中间的END也是允许的

1.3:通过read命令接受输入并打印

[root@server1 ~]# read i <<EOF
> hello
> mysql
> EOF
[root@server1 ~]# echo $i
hello

1.4:通过passwd给用户设置密码

[root@server1 ~]#  vim shuai.sh
#!/bin/bash
passwd tom <<EOF
123123                    '每一行对应每一次的交互'
123123
EOF
[root@server1 ~]#  bash a.sh 
更改用户 tom 的密码 。
新的 密码:无效的密码: 密码少于 8 个字符
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。

1.5:变量替换

#!/bin/bash
tom="1.txt"
lisi="2.txt"
cat > $tom <<EOF
this is $lisi .com 
EOF
[root@server1 ~]# cat 1.txt 
this is 2.txt .com 

1.6:变量设定

[root@server1 test]# num1=10
[root@server1 test]# echo $num1
10
[root@server1 test]# num2=$(cat <<EOF
> 100
> $num1
> EOF
> )
[root@server1 test]# echo $num2
100 10

1.7:关闭变量的替换功能

[root@server1 test]# cat <<'EOF'
> 100
> $num1
> EOF
100
$num1

1.8:去除每行之前的TAB字符

[root@server1 test]# vim b.sh
#!/bin/bash
cat <<-'EOF'                  '-表示抑制行首的TAB作用'
        this is
        $tom .com
EOF

[root@server1 test]# bash b.sh 
this is
$tom .com

1.9:通过Here Document方式是Bash支持多行注释

[root@hua opt]# vim n.sh
#!/bin/bash
echo "hello"
echo "girl"
cat <<-'EOF'
        this is 
        $school .ch
EOF
[root@hua opt]# bash n.sh 
hello
girl
this is 
$school .ch
###注释后
[root@hua opt]# vim n.sh
#!/bin/bash
: <<DD
echo "hello"
echo "girl"
DD
cat <<-'EOF'
        this is 
        $school .ch
EOF
[root@hua opt]# bash n.sh 
this is 
$school .ch

如果你尝试在脚本嵌入一小块多行数据,使用 Here Document 是很有用的,而嵌入很大的数据块是一个不好的习惯。你应该保持你的逻辑(你的代码)和你的输入(你的数据)分离,最好是在不同的文件中,除非是输入一个很小的数据集。

Here Document 最常用的功能还是向用户显示命令或者脚本的用法信息,例如类似下面的函数:

usage(){
    cat <<-END
        usage: command [-x] [-v] [-z] [file ...]
        A short explanation of the operation goes here.
        It might be a few lines long, but shouldn't be excessive.
END
}

二:Expect 介绍与用法

expect是一个自动化交互套件,主要应用于执行命令和程序时,系统以交互形式要求输入指定字符串,实现交互通信。

2.1:expect自动交互流程:
spawn启动指定进程—expect获取指定关键字—send向指定程序发送指定字符—执行完成退出.

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

yum install -y expect

2.2:基本命令(expect流程命令)

spawn:启动进程,并跟踪后续交互信息

send:向进程发送字符串,用于模拟用户的输入

该命令不能自动回车换行,一般要加、r(回车)

expect

expect的一个内部命令,判断上次输出结果里是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回

只能捕捉有spawn启动的进程的输出

interact:执行完成后保持交互状态,把控制权交给控制台

2.3:基本命令(expect内容命令)

Timeout:指定超时时间,过期则继续执行后续指令
单位是:秒
timeout -1为永不超时
默认情况下,timeout是10秒
exp_continue
允许expect继续向下执行指令
send_user
回显命令,相当于echo

2.4:基本命令(expect其他命令)

$argv参数数组

Expect脚本可以接受从bash传递的参数,可以使用[lindex $argc n]获得,n从0开始,分别表示第一个,第二个,第三个…参数

arg:参数

v:value

Expect脚本的结尾

expect脚本必须以interact或expect eof结束,执行自动化任务通常expect eof就够了

expect eof是在等待结束标志。由spawn启动的命令在结束时会产生一个eof标记,expect eof就是在等待这个标记

2.5:Expect执行方式

单一分支语法

expect "password:" {send "mypassword\r"}

多分支模式语法第一种

expect "aaa" {send "AAA\r"}
expect "aaa" {send "AAA\r"}
expect "aaa" {send "AAA\r"}
'send命令不具备回车换行功能,所以需要自己添加\r 或 \n'

多分支模式语法第二种

expect {
"aaa" {send "AAA\r"}
"bbb" {send "BBB\r"}
"ccc" {send "CCC\r"}
}
'只要匹配了aaa 或bbb或ccc中的任何一个,执行相应的send语句后就会退出该expect语句'

expect {
"aaa" {send "AAA\r";exp_continue}
"bbb" {send "BBB\r";exp_continue}
"ccc" {send "CCC\r"}
}
'exp_continue表示继续后面的匹配,如果匹配了aaa,执行完send语句后还会继续向下匹配bbb'
'捕捉内容要用双引号引起来'
'send要写在{}中,输出信息也要用双引号引起来,分号“;”要写在}里面'

-re参数表示匹配正则表达式

2.6: Expect直接执行(以ssh为例)

其中,$argv 0 代表位置变量$1

$argv 1 代表位置变量$2

#!/usr/bin/expect 是Expect二进制文件的路径 预加载环境


#!/usr/bin/expect
#超时时间
set timeout 10
#开启日志
log_file test.log
#显示信息
log_user 1

#定义变量
set hostname [lindex $argv 0]
set password [lindex $argv 1]
#追踪指令
spawn ssh root@${hostname}
#捕捉提示信息
expect {
    "connecting (yes/no)"
    {send "yes\r";exp_continue}
    "*password:"
    {send "${password}\r";}
}
#转交控制台
interact
-----------执行----------------
[root@hua opt]# chmod +x 2.sh 
[root@hua opt]# ./2.sh 192.168.1.20 123123
spawn ssh root@192.168.1.20
root@192.168.1.20's password: 
Last login: Tue Jul 28 22:01:09 2020 from 192.168.1.21

2.7:Expect嵌入执行(以ssh为例)

[root@server1 test]# vi ssh.sh 
#!/bin/bash
hostname=$1
password=$2
#expect嵌入
/usr/bin/expect <<-EOF
spawn ssh root@${hostname}

#捕捉提示信息
expect {
  "connecting (yes/no)"
  {send "yes\r";exp_continue}
  "*password:"
  {send "${password}\r";}
}
expect "*]#"
send "exit\r"
expect eof
EOF
~   
[root@server1 test]# sh ssh.sh 192.168.158.60 123123
spawn ssh root@192.168.158.60
The authenticity of host '192.168.158.60 (192.168.158.60)' can't be established.
ECDSA key fingerprint is SHA256:I3pGxKAQd78NEtldEi1ezgKT9uiA+cIcXz72pNUrfi8.
ECDSA key fingerprint is MD5:61:b6:d5:1f:7f:61:8a:40:4d:1f:28:23:42:1e:25:ab.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.158.60' (ECDSA) to the list of known hosts.
root@192.168.158.60's password: 
Last login: Wed Nov 11 20:17:21 2020 from 192.168.158.1
[root@localhost ~]# exit
登出
Connection to 192.168.158.60 closed.
[root@server1 test]# 

2.8:Expect实操

[root@server1 test]# vi tom.sh
#!/bin/bash
user=$1
password=$2
useradd $user
/usr/bin/expect <<-EOF
spawn passwd $user
expect {
      "新的 密码:"
      {send "$password\r";exp_continue}
      "重新输入新的 密码:"
      {send "${password}\r";}
}
expect "成功"
send "exit\r"
expect eof
EOF
[root@server1 test]# sh tom.sh tom2 123123
spawn passwd tom2
更改用户 tom2 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
expect: spawn id exp6 not open
    while executing
"expect "成功""

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值