Shell编程之免交互
一、Here Document
1、Here Document定义
- 使用I/O重定向的方式将命令列表提供给交互式程序
- 标准输入的一种替代品
- Here Document 是标准输 入的一种替代品,可以帮助脚本开发人员不必使用临时文件来构建输入信息,而是直接就地生产出一个文件并用作命令的标准输入,Here Document 可以与非交互式程序和命令一起使用。
2、语法格式
- 特殊字符“<<”在标记和命令之前,这样做的目的是将命令块的输出重定向到程序或命令的 stdin。
- 标记的选择要确保不会出现在其他地方,避免出现混淆。
- 两个标记之间的内容被当做是一个文件并用作“命令”的标准输入。
- 另外 Here Document 也可以与非交互式程序和命令一起使用。
命令 <<标记
...
...
标记
注意:
- 标记可以使用任意的合法字符
- 结尾的标记一定要顶格写,前面不能有任何字符
- 结尾的标记后面也不能有任何字符(包括空格)
- 开头的标记前后的空格会被省略
3、应用实列
(1)行数进行统计
[root@localhost data]#wc -l <<EOF
> test0
> test1
> test3
> EOF
3
(2)将输入保存到文件中
[root@localhost data]#cat > zzt <<EOF
> zhangsan
> wusan
> lisi
> EOF
[root@localhost data]#cat zzt
zhangsan
wusan
lisi
(3)追加输入保存到文件中
[root@localhost data]#cat >> zzt <<EOF
> 男孩
> EOF
[root@localhost data]#cat zzt
zhangsan
wusan
lisi
男孩
(4)设置密码免交互
[root@localhost data]#useradd zhantai
[root@localhost data]#passwd zhantai <<EOF
> 123123
> 123123
> EOF
更改用户 zhantai 的密码 。
新的 密码:无效的密码: 密码少于 8 个字符
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。
(5)给变量赋值
[root@localhost data]#read zz <<EOF
> beautiful
> EOF
[root@localhost data]#echo $zz
beautiful
[root@localhost data]#
(6)关闭变量替换功能
#对标记加单引号,即可关闭变量替换
[root@localhost data]#zz=$(cat <<'EOF'
> 22
> $zz
> EOF
> )
[root@localhost data]#echo $zz
22 $zz
[root@localhost data]#echo $z
beautiful
(7)去掉每行前面的tab字符
[root@localhost data]#vim test0.sh
#!/bin/bash
cat <<EOF
hello
EOF
cat <<EOF
word
EOF
[root@localhost data]#bash test0.sh
hello
word
[root@localhost data]#vim test0.sh #EOF前面添加“-”能够去掉行首的tab制表符
#!/bin/bash
cat <<-EOF
hello
EOF
cat <<-EOF
word
EOF
[root@localhost data]#bash test0.sh #加了“-”以后显示出的内容就会顶格显示
hello
word
二、Expect免交互
1、概述
Expect是建立在tcl(tool command language)语言基础上的一个工具,常被用于进行自动化控制和测试,解决shell脚本中交互的相关问题。主要应用于自动化交互式操作的场景,是一个免费的编程工具。说白了,expect就是一套用来实现自动交互功能的软件。
2、安装环境
想要用它来完成你的脚本,你需要先安装两个软件包。当然,在使用yum的情况下,我们执行这条命令就可以了。
[root@localhost data]#yum install expect.x86_64 -y
3、使用命令
(1)脚本解释器
#!/usr/bin/expect
(2)spawn
spawn 后面通常跟一个Linux执行命令,表示开启一个会话、启动进程,并跟踪后续交互信息,spawn 启动新的进程(监控,捕捉)
spawn passwd root
(3)expect
判断上次输入结果中是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回
只能捕捉由 spawn 启动的进程的输出
用于接收命令执行后的输出,然后和期望的字符串匹配
(4)send
向进程发送字符串,用于模拟用户的输入,该命令不能自动回车换行,一般要加 \r (回车) 或者 \n。
expect "密码" {send "abc123\r"}
或
expect "密码"
send "abc123\r"
#同一行send部分要有{} 换行send部分不需要有{}
##################################################
expect
"密码1"{ send "abc123\r"}
"密码2"{ send "123456\r"}
"密码3"{ send "123123\r"}
#expect支持多个分支,只要匹配了其中一个情况,执行相应的send语句后退出该expect语句
(5)expect eof结束符
expect eof
- 表示交互结束,等待执行结束,退回到原用户,与spawn对应
- 比如:切换到root用户,expect脚本默认的是等待10s,当执行完命令后,默认停留10s后,就会自动切回原用户。
interact
- 执行完成后保持交互状态,把控制权交给控制台,会停留在目标终端,这个时候就可以手工操作了,interact 后的命令不起作用。
- 如 interact 会保持在终端而不会退回到原终端,比如切换到 root 用户,会一直在 root 用户状态下。
- 如 ssh 到另一服务器,会一直在目标服务器终端,而不会切回的原服务器。
注意:expect eof 和 interact 只能二选一
(6)set
expect 默认的超时时间是10秒,通过 set 命令可以设置会话超时时间,若不限制超时时间则应设置为-1。
set timeout 5
三、应用实例
1、免交互传输文件
[root@localhost data]#vi test0.sh
#!/usr/bin/expect
spawn scp /data/passwd 192.168.10.132:/data/zzt
#捕捉 linux scp 命令,出现scp 会执行下面的操作
expect {
#进行标准输出捕获
"yes/no" { send "yes\n";exp_continue }
#只要出现yes/no 就发送yes exp_continue代表继续捕捉
"password" { send "123123\r" }
}
expect eof
#代表结束
2、创建用户设置密码
[root@localhost data]#vi test1.sh
#!/bin/bash
username=$1
useradd $username
/usr/bin/expect <<-EOF
spawn passwd $username
expect { #获取的内容和发送的内容不能在同一行否则执行不成功
"新的 密码"
{ send "123123\r";exp_continue }
"重新输入新的 密码"
{ send "123123\r"; }
}
EOF
[root@localhost data]#chmod +x test1.sh
[root@localhost data]#./test1.sh zz
spawn passwd zz
更改用户 zz 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。