一、Here Document免交互
1.Here Document概述
- 使用I/O重定向的方式将命令列表提供给交互式程序
- 标准输入的一种替代品
- 语法格式
2.Here Document的使用
使用注意事项:
标记可以使用任意合法字符;
结尾的标记一定要顶格写,前面不能有任何字符;
结尾的标记后面也不能有任何字符(包括空格);
开头标记前后的空格会被省略掉
1) 免交互重定向输出方式给变量赋值
2) 免交互设置密码
3) 免交互创建文件,编辑内容
① cat 命令重定向输出文件 EOF重定向输出传入的内容
cat > 文件 <<EOF
指定文件内容
```
EOF
cat <<EOF > 文件
指定文件内容
```
EOF
② tee命令:在免交互时同时标准输出和重定向输出
tee 文件 <<EOF
指定文件内容
```
EOF
tee 文件名 #覆盖输出,并打印操作的内容
tee -文件名 #输出到标准输出两次,- - 表示输出到标准输出三次,但不会保存到文件中
tee -a 文件名 #重定向追加
tee命令还能实现混合输出,将错误输出重定向到标准输出,通过管道符号一起保存到文件中
4)免交互过程中可以使用变量替换值
#!/bin/bash
file_path=/opt/base.repo
repo_path=/data
cat <<EOF >$file_path
[local]
name=local
baseurl=file://$repo_path
enabled=1
gpgcheck=0
EOF
5)整体赋给一个变量
6)特殊符号的用法
① 免交互代码中间使用变量,但不想引用变量的值,可以给EOF加 ' ' 单引号关闭变量或者在变量前面加\转义成普通字符
#!/bin/bash
file_path=/opt/base.repo
repo_path=/data
cat <<'EOF'
[local]
name=local
baseurl=file://$repo_path
enabled=1
gpgcheck=0
EOF
echo "$myrepo"
② 如果文件中有很多tab符号,但输出时不想显示tab符可以在EOF前面加“-”,即<<-EOF
③ 免交互做脚本注释,冒号 :后面两个EOF中间的命令就不会执行了,即: <<EOF,相当于批量注释的效果(但是一般用#更简单明了),
二、Expect免交互
1)Expect概述
- 建立在tcl之上的一个工具
- 用于进行自动化控制和测试
- 解决shell脚本中交互相关的问题
2)Expect安装(系统默认没有)
- 挂载光盘
- 制作本地YUM源
- 执行安装命令
3)编写expect免交互脚本的步骤
① 申明脚本解释器为#!/usr/bash/expect
② set命令接收位置参数传入
set 变量名1 [lindex $argv 0] #相当于变量名1=$1
set 变量名2 [lindex $argv 1] #相当于变量名2=$2
0表示执行脚本时后面跟的第一个位置参数,第二个位置参数用1表示,依次类推
set 命令还可以设置匹配超时时间
expec默认的超时时间是10秒,通过set命令可以设置会话超时时间,格式为set timeout 30若设置永不超时则应设置为 -1。
③ spawn指定交互命令,跟踪会话,如spawn passwd root
④ expect捕获匹配交互命令的提示信息
expect "命令(输入 m 获取帮助 ):"
⑤ exp_continue的作用:附加于某个expect判断项之后,实现1-2次匹配。当命令交互有不止一种情况时,如果能匹配到情况 1 的提示信息则发送 字符串1 给交互进程,接着再用情况 2 匹配提示信息发送字符串2给交互进程。如果情况1没匹配到会接着去情况 2 匹配,发送字符串2。
注意:使用执行完命令会自动退出的命令,expect{}外不需要再加expect eof结束符
expect (
“情况1” {send "字符串1\r";exp_continue;}
“情况2” {send "字符串2\r";}
)
⑥ send命令发送需要交互输入的字符串,结尾加上回车符 send "n\r";send_user 表示回显命令,相当于echo
方法一:同一行send部分需要有{}。
expect "密码" {sned "abc123\r"}
方式二:换行send部分不需要有{}
expect "密码"
send "abc123\r"
方式三:expect多个分支,只要匹配的其中一个情况,执行响应的send语句后退出该expect语句
expect
{
"字符串1" {send "12345678\r"}
"字符串2" {send "11223344\r"}
"字符串2" {send "abcdef\r"}
}
⑦ 所有交互操作完成后,使用 expect eof 或者 interact 结束会话
使用expect eof结尾,会返回原用户或终端界面
-比如从192.168.170.10远程登录到20的主机,执行结束后会返回到10的主机
使用interact结尾,会停留在切换的用户或者终端界面
-比如从192.168.170.10远程登录到20的主机,执行结束后还是停留在10的主机
4)案例
免交互实现切换至root用户,执行完后会留在执行后的环境中
#!/usr/bin/expect
#开始追踪命令
spawn su root
#免交互执行,捕捉信息并匹配
expect "密码"
send "123456\r"
expect "*]#"
send_user "ok"
#把控制权交给控制台
interact
免交互使用函数的传参,实现从一个非root用户切换到另一个非root用户,执行后退回到原用户
#!/usr/bin/expect
set timeout 5
#参数传入
set username [lindex $argv 0]
set password [lindex $argv 1]
#开始追踪命令
spawn su $username
#免交互执行,捕捉信息并匹配
expect "密码"
send "$password\r"
expect "*]$"
send "成功切换至$username 用户"
expect eof
免交互ssh远程登录
#!/usr/bin/expect
set dest_host [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh $dest_host
expect {
"Conection refused" {send_user "访问被拒\n"}
"No route to host" {send_user "目标主机离线\n"}
"(yes/no)" {send "yes\r"; exp_continue;}
"password:" {send "$password\r"}
}
interact