新茶到货,欢迎品鉴!晒足阳光的干货,shell免交互!!!

一: Shell Here Document(内嵌文档/嵌入文档)

Shell 还有一种特殊形式的重定向叫做“Here Document”,目前没有统一的翻译,你可以将它理解为“嵌入文档”“内嵌文档”“立即文档”。

所谓文档,就是命令需要处理的数据或者字符串;所谓嵌入,就是把数据和代码放在一起,而不是分开存放(比如将数据放在一个单独的文件中)。有时候命令需要处理的数据量很小,将它放在一个单独的文件中有点“大动干戈”,不如直接放在代码中来得方便。

1.1:Here Document 的基本用法为:

command <<END
  document
END

command是 Shell 命令,<<END是开始标志,END是结束标志,document是输入的文档(也就是一行一行的字符串)。

这种写法告诉 Shell 把 document 部分作为命令需要处理的数据,直到遇见终止符END为止(终止符END不会被读取)。

注意,终止符END必须独占一行,并且要定顶格写。

分界符(终止符)可以是任意的字符串,由用户自己定义,比如 END、MARKER 等。分界符可以出现在正常的数据流中,只要它不是顶格写的独立的一行,就不会被作为结束标志。

1.2:注意事项

  • 标记可以使用任意合法字符

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

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

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

【实例1】cat 命令一般是从文件中读取内容,并将内容输出到显示器上,借助 Here Document,cat 命令可以从键盘上读取内容。

[jj@localhost ~]$ cat <<END
> Shell教程
> http://c.biancheng.net/shell/
> 已经进行了三次改版
> END 
Shell教程
http://c.biancheng.net/shell/
已经进行了三次改版

<是第二层命令提示符。

正文中也可以出现结束标志END,只要它不是独立的一行,并且不顶格写,就没问题。

[jj@localhost ~]$ cat <<END
> END可以出现在行首
> 出现在行尾的END
> 出现在中间的END也是允许的
> END
END可以出现在行首
出现在行尾的END
出现在中间的END也是允许的

1.3:通过read命令接受输入并打印

[root@hua opt]# read i <<EOF
> hello boy
> my name is lisi
> EOF
[root@hua opt]# echo $i
hello boy
#只能赋予第一行的内容

1.4:通过passwd给用户设置密码

[root@shuai ~]# vim shuai.sh
#!/bin/bash
passwd liu <<EOF
123123                    '每一行对应每一次的交互'
123123
EOF
[root@shuai ~]# bash shuai.sh 
更改用户 liu 的密码 。
新的 密码:无效的密码: 密码少于 8 个字符
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。

1.5:变量替换

[root@hua opt]# vim txt.sh
#!/bin/bash
shuai="1.txt"
lisi="kgc"
cat > $shuai <<EOF
this is $lisi .com 
EOF
[root@hua opt]# ls
1.txt  EOF  hao.sh  httpd.txt  rh  ss.sh  txt.sh  xx.txt
[root@hua opt]# cat 1.txt 
this is kgc .com 

1.6:变量设定

[root@hua opt]# num1=20
[root@hua opt]# echo $num1 
20
[root@hua opt]# num2=$(cat <<EOF
> 100
> $num1
> EOF
> )
[root@hua opt]# echo $num2 
100 20

1.7:关闭变量的替换功能

[root@hua opt]# echo $num1
20
[root@hua opt]# cat <<'EOF'
> 100
> $num1
> EOF
100
$num1

1.8:去除每行之前的TAB字符

[root@hua opt]# vim b.sh
#!/bin/bash
cat <<-'EOF'                  '-表示抑制行首的TAB作用'
        this is
        $shuai .com
EOF

[root@hua opt]# bash b.sh 
this is
$shuai .com

1.9:通过Here Document方式是Bash支持多行注释

[root@hua opt]# vim n.sh
#!/bin/bash
echo "hello"
echo "girl"
cat <<-'EOF'
        this is 
        $school .ch
EOF
[root@hua opt]# bash n.sh 
hello
girl
this is 
$school .ch
###注释后
[root@hua opt]# vim n.sh
#!/bin/bash
: <<DD
echo "hello"
echo "girl"i
DD
cat <<-'EOF'
        this is 
        $school .ch
EOF
[root@hua opt]# bash n.sh 
this is 
$school .ch

总结

如果你尝试在脚本嵌入一小块多行数据,使用 Here Document 是很有用的,而嵌入很大的数据块是一个不好的习惯。你应该保持你的逻辑(你的代码)和你的输入(你的数据)分离,最好是在不同的文件中,除非是输入一个很小的数据集。

Here Document 最常用的功能还是向用户显示命令或者脚本的用法信息,例如类似下面的函数:

usage(){
    cat <<-END
        usage: command [-x] [-v] [-z] [file ...]
        A short explanation of the operation goes here.
        It might be a few lines long, but shouldn't be excessive.
END
}

二:Expect 介绍与用法

expect是一个自动化交互套件,主要应用于执行命令和程序时,系统以交互形式要求输入指定字符串,实现交互通信。

2.1:expect自动交互流程:

spawn启动指定进程—expect获取指定关键字—send向指定程序发送指定字符—执行完成退出.

注意该脚本能够执行的前提是安装了expect

yum install -y expect

2.2:基本命令(expect流程命令)

  • spawn:启动进程,并跟踪后续交互信息

  • send:向进程发送字符串,用于模拟用户的输入

    该命令不能自动回车换行,一般要加、r(回车)

  • expect

    expect的一个内部命令,判断上次输出结果里是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回

    只能捕捉有spawn启动的进程的输出

  • interact:执行完成后保持交互状态,把控制权交给控制台

2.3:基本命令(expect内容命令)

  • Timeout:指定超时时间,过期则继续执行后续指令
    • 单位是:秒
    • timeout -1为永不超时
    • 默认情况下,timeout是10秒
  • exp_continue
    • 允许expect继续向下执行指令
  • send_user
    • 回显命令,相当于echo

2.4:基本命令(expect其他命令)

  • $argv参数数组

    Expect脚本可以接受从bash传递的参数,可以使用[lindex $argc n]获得,n从0开始,分别表示第一个,第二个,第三个…参数

    arg:参数

    v:value

  • Expect脚本的结尾

    expect脚本必须以interact或expect eof结束,执行自动化任务通常expect eof就够了

    expect eof是在等待结束标志。由spawn启动的命令在结束时会产生一个eof标记,expect eof就是在等待这个标记

2.5:Expect执行方式

单一分支语法

expect "password:" {send "mypassword\r"}

多分支模式语法第一种

expect "aaa" {send "AAA\r"}
expect "aaa" {send "AAA\r"}
expect "aaa" {send "AAA\r"}
'send命令不具备回车换行功能,所以需要自己添加\r 或 \n'

多分支模式语法第二种

expect {
"aaa" {send "AAA\r"}
"bbb" {send "BBB\r"}
"ccc" {send "CCC\r"}
}
'只要匹配了aaa 或bbb或ccc中的任何一个,执行相应的send语句后就会退出该expect语句'

expect {
"aaa" {send "AAA\r";exp_continue}
"bbb" {send "BBB\r";exp_continue}
"ccc" {send "CCC\r"}
}
'exp_continue表示继续后面的匹配,如果匹配了aaa,执行完send语句后还会继续向下匹配bbb'
'捕捉内容要用双引号引起来'
'send要写在{}中,输出信息也要用双引号引起来,分号“;”要写在}里面'

-re参数表示匹配正则表达式

2.6: Expect直接执行(以ssh为例)

  • 其中,$argv 0 代表位置变量$1

    $argv 1 代表位置变量$2

  • #!/usr/bin/expect 是Expect二进制文件的路径 预加载环境


#!/usr/bin/expect
#超时时间
set timeout 10
#开启日志
log_file test.log
#显示信息
log_user 1

#定义变量
set hostname [lindex $argv 0]
set password [lindex $argv 1]
#追踪指令
spawn ssh root@${hostname}
#捕捉提示信息
expect {
    "connecting (yes/no)"
    {send "yes\r";exp_continue}
    "*password:"
    {send "${password}\r";}
}
#转交控制台
interact
-----------执行----------------
[root@hua opt]# chmod +x 2.sh 
[root@hua opt]# ./2.sh 192.168.1.20 123123
spawn ssh root@192.168.1.20
root@192.168.1.20's password: 
Last login: Tue Jul 28 22:01:09 2020 from 192.168.1.21

2.7:Expect嵌入执行(以ssh为例

[root@hua opt]# vim xx.sh
#!/bin/bash
hostname=$1
password=$2
#expect嵌入
/usr/bin/expect <<-EOF
spawn ssh root@${hostname}

#捕捉提示信息
expect {
  "connecting (yes/no)"
  {send "yes\r";exp_continue}
  "*password:"
  {send "${password}\r";}
}
expect "*]#"
send "exit\r"
expect eof
EOF
#执行
[root@hua opt]# bash xx.sh 192.168.1.20 123123
spawn ssh root@192.168.1.20
root@192.168.1.20's password: 
Last login: Tue Jul 28 22:10:07 2020 from 192.168.1.21
[root@shuai ~]# exit
登出
Connection to 192.168.1.20 closed.

2.8:Expect实操

创建用户lisi6 密码123123

[root@promote ~]# vim ss.sh
#!/bin/bash
user=$1
password=$2
useradd $user
/usr/bin/expect <<-EOF
spawn passwd $user
expect {
      "新的 密码:"
      {send "$password\r";exp_continue}
      "重新输入新的 密码:"
      {send "${password}\r";}
}
expect "成功"
send "exit\r"
expect eof
EOF
[root@promote ~]# bash ss.sh lisi6 123123
spawn passwd lisi6
更改用户 lisi6 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
expect: spawn id exp6 not open
    while executing
"expect "成功""

2.9:SSH登录

  • 首次登录
  • 正常登录
  • 连接被拒绝,可能是ssh没开,或者端口不对,或者防火墙限制
#!/bin/bash
hostname=$1
password=$2
/usr/bin/expect <<-EOF
  spawn ssh $hostname
  expect {
        "connection refused" exit
        "Name or service not known" exit
        "to continue" {send "yes\r";exp_continue}
        "password:" {send "$password\r"}
}
expect "*]#"
send "exit\r"
expect eof
EOF
#正常登录
[root@hua opt]# ./ssh.sh 192.168.1.20 123123
spawn ssh 192.168.1.20
root@192.168.1.20's password: 
Last failed login: Tue Jul 28 22:56:10 CST 2020 from 192.168.1.21 on ssh:notty
There was 1 failed login attempt since the last successful login.
Last login: Tue Jul 28 22:30:52 2020 from 192.168.1.21
[root@shuai ~]# exit
登出
Connection to 192.168.1.20 closed.
[root@hua opt]# vim ssh.sh

说明:经过这次尝试些expect,给我的感觉是expect对格式的要求比较高,比如花括号之间必须有空格啊之类的,所以如果有报错,大家可以仔细观察一下是不是语法格式错误了。

  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。
<!DOCTYPE html> <html> <head> <title>介绍普洱茶</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <header> <h1>普洱茶介绍</h1> <nav> <ul> <li><a href="#history">茶的历史</a></li> <li><a href="#process">茶的制作工艺</a></li> <li><a href="#culture">茶古马道</a></li> <li><a href="#product">产品</a></li> </ul> </nav> </header> <main> <section id="history"> <h2>茶的历史</h2> <p>普洱茶是一种历史悠久的茶,起源于云南。它最初被称为“云南茶”,后来才改称为普洱茶。普洱茶的历史可以追溯到2500多年前,当时它是作为贡品进献给皇帝的。在宋朝时期,普洱茶开始被广泛饮用,成为了一种重要的商品。</p> </section> <section id="process"> <h2>茶的制作工艺</h2> <p>普洱茶的制作过程分为两个阶段:生茶和熟茶。生茶是指未经过发酵的普洱茶,它的外观呈绿色,口感苦涩。熟茶是指经过发酵处理的普洱茶,它的外观呈深红色,口感醇香。普洱茶的制作工艺十分繁琐,需要经过揉捻、杀青、发酵等多个步骤。</p> </section> <section id="culture"> <h2>茶古马道</h2> <p>普洱茶有着深厚的文化底蕴,在中国茶文化中占有重要地位。普洱茶的饮用方式也很有讲究,需要注意泡茶的时间、水温、茶具等方面。此外,普洱茶还有着很多传说和典故,比如“普洱七子”和“千年古树”等。</p> </section> <section id="product"> <h2>产品</h2> <p>普洱茶的品种繁多,有生茶、熟茶、老茶、新茶等多种类型。其中,普洱茶的年份和产地是影响它品质的重要因素。普洱茶有着浓郁的香气和独特的口感,深受茶友们的喜爱。</p> </section> </main> <footer> <p>版权 © 2022 普洱茶介绍</p> </footer> </body> </html>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值