目录
一、多行重定向
举例1:使用read命令接收用户的输入值会有交互过程
举例2:设置变量的值
举例3:创建用户密码
举例4:使用多行重定向写入文件中(以repo文件举例)
举例5:变量设定
二、免交互expect
ssh连接免交互
定义变量
编辑 使用位置变量的方式
测试题:给3台主机都创建test用户,并生成密码
一、多行重定向
可以理解为这是标准输入的一种替代品,可以帮助脚本开发人员不必使用临时文件来构建输入信息,可以直接产生一个文件,输入文件信息,常与非交互程序和命令一起使用
语法格式
命令<< 标记
....
......
标记
注意事项:
1、表示可以使用任意的合法字符(通用的字符是EOF表示end of file)
2、结尾的标记是一定要顶格写,前面不能有任何字符(包括空格)
3、结尾的标记后面也不能有任何字符(包括空格)
4、开头标记前后空格会被省略掉
5、单引号变量双引号
举例1:使用read命令接收用户的输入值会有交互过程
[root@localhost test]#read i <<EOF
> 10
> EOF
[root@localhost test]#echo $i
10
举例2:设置变量的值
举例3:创建用户密码
举例4:使用多行重定向写入文件中(以repo文件举例)
[root@localhost cs]#cat repo.sh
#!/bin/bash
cat > /cs/http.repo <<EOF
[http]
name=http
baseurl=http://192.168.20.8/
gpgcheck=0
EOF
举例5:变量设定
Here Document 也支持使用变量,如果标记之间有变量被使用,会先替换变量值。如 果想要将一些内容写入文件,除了常规的方法外,也可以使用 Here Document。如果写入 的内容中包含变量,在写入文件时要先将变量替换成实际值,在结合 cat 命令完成写入。
[root@localhost cs]#cat repo.sh
#!/bin/bash
ip="192.168.20.8"
filename="http.repo"
cat > /cs/${filename} <<EOF
[http]
name=http
baseurl=http://${ip}/
gpgcheck=0
EOF
[root@localhost cs]#bash repo.sh
[root@localhost cs]#ls
http.repo local.repo repo.sh
[root@localhost cs]#cat http.repo
[http]
name=http
baseurl=http://192.168.20.8/
gpgcheck=0
EOF加上双引号,表示对重定向内容的变量强引用
二、免交互expect
定义:
是建立在tcl(tool command language)语言基础上的一个工具,常被用于进行自动化控制和测试,解决shell脚本中交互的相关问题
基本命令:
(1)脚本解释器
expect 脚本中首先引入文件,表明使用的事哪一种shell
#!/usr/bin/expect
(2)spawn
spawn 后面通常跟一个Linux执行命令,表示开启一个会话、进程,并跟踪后续交互信息
例: spawn passwd root
(3)expect
判断上次输出结果中是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回;只能捕捉有swpan启动的进程输出;用于接受命令执行后的输出,然后和期望的字符串匹配
(4)send
向进程发送字符串,用于模拟用户的输入,该命令不能自动回车换行,要加 \r (回车) 或者\ n
学习相关的命令
spawn ##表示开启监控、捕捉模式,后面跟着命令,如ssh,scp等
expect ##表示开始捕捉,即是从进程开始接收字符串,后面是花括号,表示捕捉的内容{}
send ##表示遇到捕捉的关键字,send免交互要做的事,即向进程发送字符串
exp_continue ##表示继续捕捉,一般是连续的操作,比如向ssh需要先回答yes,然后继续捕捉password
expect eof ##表示停留10秒以后,自动退出,与spawn相对应
interact ##表示停留,不再退出
ssh连接免交互
[root@localhost cs]#cat ssh.txt
#!/usr/bin/expect
spawn ssh 192.168.20.8 ##spawn表示开启捕捉模式
expect { ##expect表示开始捕捉
"yes/no" {send "yes\n";exp_continue }
"password" {send "123\n"}##yes/no以及password为捕捉关键字
}
expect eof ##表示停留10秒退出
(5) 结束符
expect eof
表示交互结束,等待执行结束,退回到原用户,与spawn对应
比如切换到root用户,expect 脚本默认的等待时间是10s,当执行王命令后,默认停留10s后,自动切回原用户.
interact
执行完成后保持交互状态, 把控制权交给控制台,会停留在目标终端而不是退回到原终端,这时候就可以手工操作了,interact后命令不再起作用,比如interact后添加exit,并不会退出root用户。而如果没有interact则登录完成后会退出,而不是留在远程终端上。
使用interact会保持在终端而不会退回原终端,比如切换到root用户,会一直在root用户状态下;比如ssh到另一台服务器,会一直在目标服务器终端而不会切回原服务器。
需要注意的是,expect eof 与 interact 只能二选一。
(6)set
expect 默认的超时时间是10秒,通过set 命令可以设置会话超时时间,若不限制超时时间则应设置为-1
例子: set timeout 30 set ip 192.168.20.30 set user root
定义变量
[root@localhost cs]#cat ssh.txt
#!/usr/bin/expect
set ip 192.168.20.8 ##设置 ip变量
set user root ##设置user变量
set id lisi ##设置id变量
set pass 123 ##设置pass变量
spawn ssh ${user}@${ip}
expect {
"yes/no" {send "yes\n";exp_continue}
"password" {send "${pass}\n"}
}
expect "#" {send "useradd ${id}\n"}
expect "#" {send "echo ${pass}|passwd ${id} --stdin\n"}
expect eof ##所有事干完再退出
[root@localhost cs]#cat ssh.txt
#!/usr/bin/expect
set ip 192.168.20.8
set user root
set id lisi
set pass 123
spawn ssh ${user}@${ip}
expect {
"yes/no" {send "yes\n";exp_continue}
"password" {send "${pass}\n"}
}
expect "#" {send "useradd ${id}\n"}
expect "#" {send "echo ${pass}|passwd ${id} --stdin\n"}
expect "#" {send "exit\n"} ##表示退出
interact ##等待一切都回到原本的控制台再结束
使用位置变量的方式
#!/usr/bin/expect
#参数传入
set host [lindex $argv 0] #理解为host=$1
set pass [lindex $argv 1] #理解为pass=$2
spawn su $host #开始追踪命令
expect "密码:" {send "$pass\n"}
#免交互执行,捕捉信息并匹配
expect "$" {send "echo hello\n"}
##send_user "hello" ##send_user表示回显命令与echo相同
#把控制权交给控制台
expect "$" {send "exit\n"}
interact
#expect eof
测试题:给3台主机都创建test用户,并生成密码
[root@localhost cs]#cat test.sh
#!/bin/bash
net="192.168.20."
pass=123
host="
6
8
18
10
"
for i in $host
do
ip=${net}${i}
/usr/bin/expect <<EOF
spawn ssh ${ip}
expect {
"yes/no" {send "yes\n";exp_continue }
"password" {send "${pass}\n"}
}
expect "#" {send "useradd test\n"}
expect "#" {send "echo ${pass}|passwd test --stdin\n"}
expect "#" {send "exit\n"}
interact
EOF
done