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
相关推荐
软件技术员18 分钟前
Let‘s Encrypt SSL证书:acmessl.cn申请免费3个月证书
服务器·网络协议·ssl
耗同学一米八30 分钟前
2024 年河北省职业院校技能大赛网络建设与运维赛项样题四
运维·网络
一条晒干的咸魚1 小时前
【Web前端】创建我的第一个 Web 表单
服务器·前端·javascript·json·对象·表单
东华果汁哥1 小时前
【linux 免密登录】快速设置kafka01、kafka02、kafka03 三台机器免密登录
linux·运维·服务器
肖永威2 小时前
CentOS环境上离线安装python3及相关包
linux·运维·机器学习·centos
mengao12342 小时前
centos 服务器 docker 使用代理
服务器·docker·centos
布鲁格若门2 小时前
CentOS 7 桌面版安装 cuda 12.4
linux·运维·centos·cuda
Eternal-Student2 小时前
【docker 保存】将Docker镜像保存为一个离线的tar归档文件
运维·docker·容器
C-cat.2 小时前
Linux|进程程序替换
linux·服务器·microsoft
dessler2 小时前
云计算&虚拟化-kvm-扩缩容cpu
linux·运维·云计算