Shell编程之免交互

一、Here Document免交互

1.1 Here Document概述

  • 使用I/O重定向的方式将命令列表提供给交互式程序或命令,比如ftp、passwd、sudo、ssh、cat或read命令。

  • 是标准输入的一种替代品,可以帮助脚本开发人员不必使用临时文件来构建输入信息,而是直接就地生产出一个"文件"并用作"命令"的标准输入。

  • Here Document也可以与非交互式程序和命令一起使用。

    命令 <<标记 (此处标记的前后面可以有空格)
    ...
    内容 #标记之间是传入内容
    ...
    标记 #结尾的标记字符要和开头的标记字符,保持相同的大小写,并且结尾标记必须要顶格写

注意事项:

  1. 表示可以使用任意的合法字符(通用的字符是EOF表示end of file)
  2. 结尾的标记是一定要顶格写,前面不能有任何字符(包括空格)
  3. 结尾的标记后面也不能有任何字符(包括空格)
  4. 开头标记前后空格会被省略掉

二、应用示例

1 直接把输入的内容从命令行输出
[root@localhost /home]#cat <<EOF
> hello 
> moto
> EOF
hello 
moto
2 输入保存到文件中
[root@localhost /home]#cat >name<<EOF
> zhangsan
> lisi
> wangwu
> EOF
[root@localhost /home]#cat name
zhangsan
lisi
wangwu
3 追加输入保存到文件
[root@localhost /home]#cat >>name<<EOF
> xiaoming
> EOF
[root@localhost /home]#cat name 
zhangsan
lisi
wangwu
xiaoming
4 对行数进行统计
[root@localhost /home]#wc -l <<EOF
> test1
> test2
> test3
> EOF
3
5 给变量赋值
#通过read 命令接收输入并打印,输入值是两个EOF标记之间的部分,作为变量 a 的值
[root@localhost /home]#read a <<EOF
> 8
> EOF
[root@localhost /home]#echo $a
8
6 免交互设置密码
[root@localhost /home]#useradd laowang
[root@localhost /home]#passwd laowang <<EOF
> 123456
> 123456
> EOF
更改用户 laowang 的密码 。
新的 密码:无效的密码: 密码少于 8 个字符
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。
7 变量替换
[root@localhost /home]#vim test.sh
#!/bin/bash
doc_file="gkd.txt"
i="nanjing"
cat > $doc_file <<EOF
welcome to $i
EOF

[root@localhost /home]#sh test.sh 
[root@localhost /home]#cat gkd.txt 
welcome to nanjing
8 整体赋值给变量,用echo将变量值打印出来
[root@localhost /home]#vim test2.sh
#!/bin/bash
test="you are very good!"
mylife=$(cat <<EOF 
冲冲冲!
干就完了!!!
$test
EOF
)
echo $mylife

[root@localhost /home]#sh test2.sh 
冲冲冲! 干就完了!!! you are very good!
9 关闭变量替换的功能
#对标记加单引号,即可关闭变量替换
[root@localhost /home]#aa=$(cat <<'EOF'
> 10
> $a
> EOF
> )
[root@localhost /home]#echo $aa
10 $a
[root@localhost /home]#echo $a
8
10 去掉每行之前的 TAB 字符(顶格显示)
[root@localhost /home]#vim test3.sh
#!/bin/bash
cat <<EOF
        hello
EOF
cat <<EOF
        word
EOF

[root@localhost /home]#sh test3.sh 
	hello
	word

[root@localhost /home]#vim test3.sh     #EOF前面添加"-"能够去掉行首的tab制表符
#!/bin/bash
cat <<-EOF
        hello
EOF
cat <<-EOF
        word
EOF

[root@localhost /home]#sh test3.sh     #加了"-"以后显示出的内容就会顶格显示
hello
word
11 多行注释
[root@localhost /home]#vim test4.sh

#!/bin/bash
: <<EOF                              #冒号表示多行注释,开头的标记内容不会被执行
hello?
who are you?
EOF
echo "What is the matter with you?"

[root@localhost /home]#sh test4.sh 
What is the matter with you?
  1. Bash 的默认注释是"#",该注释方法只支持单行注释,在 Shell 脚本的工作中,"#"右侧的任何字符串,bash 都会将其忽略。
  2. " : "代表什么都不做的空命令。中间标记区域的内容不会被执行,会被bash 忽略掉,因此可达到批量注释的效果。

三、Expect 免交互

1、概述

expect 是一个免费的编程工具,用来实现自动的交互式任务,而无需人为干预,就是一套用来实现自动交互功能的软件。且想要用之前先下载 Expect。

[root@localhost /home]#yum install -y expect

2、基本命令

1、脚本解释器

expect 脚本中首先引入文件,表明使用的是哪一个shell

#!/usr/bin/expect
2、spawn

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

spawn passwd root
3、 expect
  • 判断上次输入结果中是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回
  • 只能捕捉由 spawn 启动的进程的输出
  • 用于接收命令执行后的输出,然后和期望的字符串匹配
4、 send

向进程发送字符串,用于模拟用户的输入,该命令不能自动回车换行,一般要加 \r (回车) 或者 \n

expect "密码" {send "abc123\r"}   #同一行send部分要有{}
或
expect "密码"
send "abc123\r"       #换行send部分不需要有{}

expect          
"密码1"{ send "abc123\r"}
"密码2"{ send "123456\r"}
"密码3"{ send "123123\r"}

#expect支持多个分支,只要匹配了其中一个情况,执行相应的send语句后退出该expect语句
5、 结束符

expect eof

  1. 表示交互结束,等待执行结束,退回到原用户,与spawn对应
  2. 比如:切换到root用户,expect脚本默认的是等待10s,当执行完命令后,默认停留10s后,就会自动切回原用户

interact

  1. 执行完成后保持交互状态,把控制权交给控制台,会停留在目标终端,这个时候就可以手工操作了,interact 后的命令不起作用
  2. 比如 interact 会保持在终端而不会退回到原终端,比如切换到 root 用户,会一直在 root 用户状态下
  3. 比如2 ssh 到另一服务器,会一直在目标服务器终端,而不会切回的原服务器

需要注意的是:expect eof 与 interact 只能二选一

su
zhangsan -> lisi
ssh192.168.80.10 ->192.168.80.20

使用expect eof会出现如下情况:
zhangsan -> lisi --expect eof--> 退回到原用户zhangsan
192.168.80.10 -> 192.168.80.20 --expect eof--> 退回到原IP地址:192.168.80.10

使用interact会出现如下情况:
zhangsan -> lisi --interact--> 仍然保持用户lisi的状态
192.168.80.10 ->192.168.80.20 --interact--> 仍然保持在IP地址:192.168.80.20
6 set

expect 默认的超时时间是10秒,通过 set 命令可以设置会话超时时间,若不限制超时时间则应设置为-1

set timeout 20

Expect 案例

免交互修改密码:

[root@test1 opt]# vim passwd.sh 
 
#!/usr/bin/expect              #expect的路径指定使用expect编译器
set timeout 3                  #设置退时间
 
spawn passwd zjf               #开启修改密码
 
expect "新的 密码:"            #捕获
send "123\r"                  #设置密码
expect "重新输入新的 密码:"     #捕获
send "123\r"                  #设置密码
 
expect eof                    #退出

免交互方式实现SSh登录:

#!/usr/bin/expect
set ip 192.168.198.12
set user root
set passwd 000000  
set timeout 5
spawn ssh $user@$ip
expect {
  "yes/no" {send "yes\n";exp_continue}
  "password" {send "${passwd}\n"}
}
interact
相关推荐
娶不到胡一菲的汪大东8 分钟前
Ubuntu概述
linux·运维·ubuntu
阿里嘎多学长18 分钟前
docker怎么部署高斯数据库
运维·数据库·docker·容器
Yuan_o_21 分钟前
Linux 基本使用和程序部署
java·linux·运维·服务器·数据库·后端
云云32130 分钟前
怎么通过亚矩阵云手机实现营销?
大数据·服务器·安全·智能手机·矩阵
灯火不休➴36 分钟前
[Xshell] Xshell的下载安装使用、连接linux、 上传文件到linux系统-详解(附下载链接)
linux·运维·服务器
小峰编程38 分钟前
独一无二,万字详谈——Linux之文件管理
linux·运维·服务器·云原生·云计算·ai原生
卜及中38 分钟前
【Linux】资源隔离机制 — 命名空间(Namespace)详解
linux·服务器·php
明 庭39 分钟前
Ubuntu下通过Docker部署Caddy服务器
服务器·ubuntu·docker
MuLogin_Browser1 小时前
如何保障多个Facebook账号稳定运行:一账号一稳定IP?
服务器·tcp/ip·facebook
聚名网1 小时前
域名和服务器是什么?域名和服务器是什么关系?
服务器·前端