Shell编程之免交互

一、Here Document免交互

1:概述

Here Document 是一个特殊用途的代码块,它在 Linux Shell 中使用 I/O 重定向的方式将命令列表提供给交互式程序或命令,比如 ftp、cat 或 read 命令,Here Document 是标准输入的一种替代品

复制代码
语法格式:
    命令 <<标记
    
    ...
    
    ...
    
    标记
  • Here Document 也可以与非交互式程序和命令一起使用
    • 标记可以使用任意的合法字符

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

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

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

      //用wc -l的命令统计输入的文字的行数
      //拓展:wc -l可以显示行数,需要参数;例如: ls | wc -l
      [root@localhost~# vim here_wc_count.sh
      #!/bin/bash
      wc -l <<EOF //Here Document 语法结构
      Line1 //EOF 之间是传入内容
      Line2
      EOF
      [root@localhost ~]# chmod +x here_wc_count.sh
      [root@localhost ~]# ./here_wc_count.sh
      2

2:Here Document免交互

(1)利用read命令接受输入并打印

通常使用read 命令接收用户的输入值时会有交互过程,尤其是在脚本执行过程中遇到read 命令,脚本会停下来等待用户输入值后才会继续,本示例中的输入值是两个 EOF 标记之间的部分,也就是"Hi",这将作为变量的值。在最后 echo 打印变量i的值,其值为"Hi"

复制代码
[root@localhost ~]# vim here non interactive read.sh
#!/bin/bash
read i<<EOF
Hi
EOF
echo $i
[root@localhost ~]# chmod +x here_non interactive_read.sh
[root@localhost ~]# ./here non interactive read.sh
[root@localhost ~]# Hi
(2)利用passwd给用户添加密码

通过 passwd 命令给 jery 用户设置密码,为避免重复交互,可使用 Here Document的方式,EOF 标记之间的两行是输入的密码和确认密码,两行内容必须保持一致,否则密码设置不成功

复制代码
[root@localhost ~# vim here non interactive passwd.sh
#!/bin/bash
passwd jerry <<EOF
This is password            //这两行是输入密码和确认密码
This is password
EOF
[root@localhost ~]# chmod +x here non interactive passwd.sh
[root@localhost ~]# ./here non interactive passwd.sh
[root@localhost ~]#

3:Here Document变量设定

Here Document也支持使用变量,如果标记之间有变量被使用,会先替换变量值

复制代码
[root@localhost ~]# vim here var replace.sh#!/bin/bash
doc file="2019.txt"
i="company'
cat > $doc file << HERE
Take him from home to $i
HERE
[root@localhost ~]# chmod +x here_var_replace.sh
[root@localhost~]# ./here_var_replace.sh
[root@localhost ~]# cat 2019.txt
Take him from home to company
标记内变量i的值被替换成了"company",最终结果输出到$doc file 内,其值为 2019.txt

[root@localhost ~l# vim here var set.sh
#!/bin/bash
ivar="Great! Beautyfu!!"
myvar=$(cat <<EOF            //将 Here Document 整体赋值给变量
This is Line 1.
That are Sun.Moon and Stars.
$ivar            //输出时会进行变量替换
EOF
)
echo $myvar
[root@localhost ~l# sh here var set.sh
This is Line 1. That are Sun.Moon and Stars. Great! Beautyful!
$ivar 先进行了替换,之后再转向输出,交由cat 显示出来,其结果放置到$0)中

4:Here Document格式控制

(1)关闭变量替换功能
复制代码
[root@localhost ~]# cat here format shut.sh
#!/bin/bash
cat <<'EOF'        //对标记加单引号,即可关闭变量替换
This is Line 1.
$kgc
EOF
[root@localhost ~l# sh here format shut.shThis is Line 1.
$kgc            //$kgc 没有发生改变,不做变量替换
(2)去掉每行之前的TAB字符
复制代码
[root@localhost ~]# vim here format tab.sh
#!/bin/bash
cat <<-'EOF'
         This is Line 1.
         $kgc
EOF
[root@localhost ~]# sh here format tab.shThis is Line 1.
$kgc            //输出结果同上一示例

5:Here Document多行注释

Bash 的默认注释是"#",该注释方法只支持单行注释,在 Shel 脚本的工作中,"#"右侧的任何字符串,bash 都会将其忽略。Here Document的引入解决了多行注释的问题

复制代码
:<< DO-NOTHING
第一行注释
第二行注释
......
DO-NOTHING
结构中":"代表什么都不做的空命令。中间标记区域的内容不会被执行,会被bash 忽略掉,因此可达到批量注释的效果

[root@localhost ~]# vim here_multi.sh#!/bin/bash
:<<BASH-HERE        //多行注释
the first comment.
the second comment.
test line.
BASH-HERE
echo "exec string."
[root@localhost ~# sh here multi.sh
exec string.
脚本用于演示 Shel 中多行注释,":"开头的 Here Document 标记内容不会被执行

二、expect免交互

1:概述

建立在tcl之上的一个工具,用于进行自动化控制和测试,解决shell脚本中交互相关的问题

2:expect安装

复制代码
(1)挂载光盘
[root@localhost ~]# mount /dev/sr0 /media            //通过 mount 命令挂载光盘到本地的/media 目录
(2)制作本地 YUM 源
[root@localhost ~# vim /etc/yum.repos.d/local.repo
name=localrepo
baseurl=file:///media
gpgcheck=0
//进入/etc/yum.repos.d目录,删除默认存在的所有仓库配置文件,新建文件,并命名为local.repo,其中后缀.repo 是必须的
[root@localhost ~]# yum clean all
[root@localhost ~]# yum make cache
//编写完配置文件后,执行以下命令删除 yum 缓存并更新
(3)执行安装命令
[root@localhost ~]# yum -y install expect    

3:基本命令介绍

(1)脚本解释器
复制代码
#!/usr/bin/expect
(2)expect/send

expect 命令用来判断上次输出结果里是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回,只能捕捉由spawn 启动的进程的输出,expect 接收命令执行后的输出,然后和期望字符串匹配,若匹配成功则执行相应的send 向进程发送字符串,用于模拟用户的输入。Send 发送的命令不能自动回车换行,一般要加\r(回车)

复制代码
方法一
expect "$case1" {send "$respond1\r"}
方法二
expect "$case1"
send "$response1\r"
方法三
expect 支持多个分支
expect
{
  "$case1"{send "$response1\r"}
  "$case2"{send "$response2\r"}
  "$case3"{send "$response3\r"}  
}
(3)spawn

spawn 后面通常跟一个命令,表示开启一个会话、启动进程,并跟踪后续交互信息

复制代码
spawn Linux执行命令
想要跟踪切换用户的交互信息
spawn su root
(4)结束符
  • expect eof :等待执行结束,若没有这一句,可能导致命令还没执行,脚本就结束了
  • interact : 执行完成后保持交互状态,把控制权交给控制台,这时可以手动输入信息
    • 需要注意的是,expect eof 与 interact 只能二选一
(5)set
  • 设置超时时间,过期则继续执行后续指令
  • 单位是秒
  • 默认情况下,timeout是10秒
  • timeout -1表示永不超时

set timeout 30

(6)exp_continue

附加于某个expect判断项之后,可以使该项被匹配后,还能继续匹配该expect-判断语句内的其他项。exp_continmue类似于控制语句中的continue 语句。表示允许expect继续向下执行指令

(7)send_user

回显命令,相当于echo

(8)接受参数
  • expect脚本可以接受从bash传递的参数
  • 可以使用[lindex %argv n]获得
  • n从0开始,分别表示第一个、第二个、第三个...参数

4:expect语法

1、语法结构
(1)单一分支语法

单一分支用于简单的用户交互,当监控命令的标准输出满足 expect 指定的字符串时,向标准输入发送 send 指ba定的字符串

复制代码
expect "password:" {send "mypassword\r";}
(2)多分支模式语法

多分支用于复杂的用户交互,一般情况下输出内容可能有多个,根据不同的输出内容,分别向标准输入发送不同的内容

复制代码
expect
{
    "aaa"{send "AAA\r"}
    "bbb"{send "BBB\r"}
    "ccc"{send "CCC\r"}
}
另一种的多分支结构
expect
{
    "aaa"{send "AAA";exp_continue}
    "bbb"{send "BBB";exp_continue}
    "ccc"{send "CCC"}
}
2、expect执行方式
(1)直接执行
复制代码
[root@localhost ~]# more direct.sh
[root@localhost ~l# chmod +x direct.sh
[root@localhost ~]# ./direct.sh 127.0.0.1 123456        //参数为主机ip 和密码
(2)嵌入执行
复制代码
[root@localhost ~]# more implant.sh
相关推荐
戒不掉的伤怀3 分钟前
【Navicat 连接MySQL时出现错误1251:客户端不支持服务器请求的身份验证协议;请考虑升级MySQL客户端】
服务器·数据库·mysql
超喜欢下雨天3 分钟前
服务器安装 ros2时遇到底层库依赖冲突的问题
linux·运维·服务器·ros2
搬码临时工9 分钟前
小企业如何搭建本地私有云服务器,并设置内部网络地址提供互联网访问
运维·服务器
old-six-programmer29 分钟前
NAT 类型及 P2P 穿透
服务器·网络协议·webrtc·p2p·nat
梓贤Vigo34 分钟前
【Axure视频教程】大小图轮播
交互·产品经理·axure·原型·中继器
tan77º1 小时前
【Linux网络编程】网络基础
linux·服务器·网络
风口上的吱吱鼠1 小时前
Armbian 25.5.1 Noble Gnome 开启远程桌面功能
服务器·ubuntu·armbian
18你磊哥1 小时前
Windows 本地安装部署 Apache Druid
运维·debian
hi星尘1 小时前
深度解析:Java内部类与外部类的交互机制
java·开发语言·交互
笑衬人心。1 小时前
Ubuntu 22.04 + MySQL 8 无密码登录问题与 root 密码重置指南
linux·mysql·ubuntu