目录
一 免交互概述
1.1 定义
使用I/O重定向的方式将命令列表提供给交互式程序,标准输入的一种替代品
1.2 语法格式
命令 <<标记
… #标记之间是传入内容
…
标记
注意事项:
- 标记可以使用任意合法字符(通常为EOF)
- 结尾的标记一定要顶格写,前面不能有任何字符
- 结尾的标记后面也不能有任何字符(包括空格)
- 开头标记前后的空格会被省略掉
1.3 示例
免交互方式实现对行数的统计,将要统计的内容于标记“EOF”之间,直接将内容传给wc -l 来统计
[root@localhost ~]# wc -l <<EOF
> line1
> line2
> EOF
2
通过read命令接收输入并打印,输入值是两个EOF标记之间的部分,作为变量i的值
[root@localhost ~]# read i <<EOF
> hello
> EOF
[root@localhost ~]# echo $i
hello
通过passwd给用户设置密码
[root@localhost ~]# passwd lisi <<EOF
> Abc123 //这两行是输入的密码和确认密码
> Abc123
> EOF
1.4 支持变量替换
[root@localhost ~]# vim ceshi2.sh
#!/bin/bash
file="EOF1.txt"
i="school"
cat > $file <<EOF
I am going to $i
EOF
cat EOF1.txt
[root@localhost ~]# chmod +x ceshi2.sh
[root@localhost ~]# ./ceshi2.sh
I am going to school
1.5 整体赋值给变量
#!/bin/bash
var="Great! I am going to school!"
myvar=$(cat <<EOF
This is line 1
Today is Monday
$var
EOF
)
echo $myvar
1.6 关闭变量替换功能
#!/bin/bash
var="Great! I am going to school!"
myvar=$(cat <<'EOF' //对标记加单引号,即可关闭变量替换
This is line 1
Today is Monday
$var
EOF
)
echo $myvar
1.7 去掉每行之前的TAB字符或者空格
#!/bin/bash
var="Great! I am going to school!"
myvar=$(cat <<-EOF //对标记前加“-”,即可抑制各行首TAB或空格
This is line 1
Today is Monday
$var
EOF
)
echo $myvar
1.8 多行注释
#!/bin/bash
var="Great! I am going to school!"
: <<-EOF //多行注释,“:”开头的标记内容不会被执行
This is line 1
Today is Monday
$var
EOF
echo "abcd"
二 Expect概述
2.1 定义
Expect是建立在tcl语言基础上的一个工具,常被用于进行自动化控制和测试,解决shell脚本中交互相关的问题
[root@localhost ~]# rpm -q expect //查看expect相关信息
expect-5.45-14.el7_1.x86_64
[root@localhost ~]# rpm -q tcl //查看tcl相关信息
tcl-8.5.13-8.el7.x86_64
[root@localhost ~]# yum -y install expect //如果没有安装,则用yum安装
2.2 基本命令
-
脚本注释器
expect脚本中首先引入文件,表明使用的是哪一个shell
#!/usr/bin/expext -
spawn
spawn后面通常跟一个命令,表示开启一个会话,启动进程,并跟踪后续交互信息
例: spawn passwd root -
expect
判断上次输出结果中是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回,只能捕捉由spawn启动的进程的输出;用于接收命令执行后的输出,然后和期望的字符串匹配 -
send
向进程发送字符串,用于模拟用户的输入;该命令不能自动回车换行,一般要加\r(回车) -
结束符
expect eof
等待执行结束,退回到原用户,与spawn对应
expect脚本默认的是等待10s,当执行完ls命令后,默认停留10s后,自动切回了原用户
interact
执行完成后保持交互状态,把控制权交给控制台,会停留在目标终端而不会退回到原终端,这个时候可以手工操作了,interact后的命令不起作用,比如interact后添加exit,并不会退出root用户,而如果没有interact则登录完成后会退出,而不是留在远程终端上。
使用interact会保持在终端而不会退回到原终端,比如切换到root用户,会一直在root用户状态下;比如ssh到另一个服务器,会一直在目标服务器终端,而不会切回到原终端
注意:expect eof 与 interact 只能二选一。
-
set
expect 默认的超时时间是10秒,通过set命令可以设置会话超时时间,若不限制超时时间则应设置为-1
例:set timeout 30 -
exp_continue
exp_continue 表示允许 expect 继续向下执行命令
例:
expect
{
"aaa" {send "AAA"; exp_continue}
"bbb" {send "BBB"; exp_continue}
"ccc" {send "CCC"}
}
-
send_user
send_user 表示回显命令,相当于 echo -
接收参数
expect 脚本可以接受从bash命令行传递的参数,使用[lindex $argv n]获得。其中n从0开始,分别表示第一个,第二个,第三个…参数。
例:
set hostname [lindex $argv 0]
set password [lindex $argv 1]
2.3 示例
创建用户并设置密码
#!/bin/bash
user=$1
passwd=$2
#非交互命令放在expect外面
useradd $user
#开始免交互执行
expect <<EOF
spawn passwd $user #开启一个进程跟踪passwd命令,expect只能捕捉该进程信息
expect {
"New password:" {send "${passwd}\r"; exp_continue} #匹配输出信息“New password:”;自动输入密码
"password:" #匹配输出信息“password:”
{send "${passwd}\r"} #自动输入密码
}
expect eof #等待结束标记
EOF