Shell编程之免交互

目录

一、Here Document免交互

1.1 免交互定义

1.2 语法格式

1.3 示例

示例1:直接把输入的从命令行输出

示例2:输入保存到文件

​编辑

示例3:追加输入到文件

 示例4:创建yum源

示例5:通过read命令接收输入并打印,输入值是两个EOF标记之间的部分,也就是520,这将作为变量a的值

 示例6:通过passwd给用户设置密码

1.4 变量设定(支持变量替换)

1.4.1 在写入文件时要先将变量值换成实际值,再结合cat命令完成写入

1.5 格式控制

1.5.1 关闭变量替换的功能

1.6 去掉每行之前的 TAB 字符

1.7 多行注释

二、Expect 免交互

1.1 概述

1.2 环境安装

1.3 基本命令

1.3.1 脚本解释器

1.3.2 spawn

1.3.3 expect

1.3.4 send

1.3.5 结束符

1.3.6 set

1.3.7 exp_continue

1.3.8 send_user

1.3.9 接收参数

1.4 用法示例

示例1:ssh免交互登录到远程服务器

示例2:在对方服务器上进行一下操作后再退出可执行以下脚本

示例3:引用位置变量

 示例4:创建用户并设置用户密码

总结


一、Here Document免交互

1.1 免交互定义

(1)使用I/O重定向的方式将命令列表提供给交互式程序

(2)标准输入的一种替代品,可以帮助脚本开发人员不必使用临时文件来构建输入信息,而是直接就地 生产出一个文件并用作命令的标准输入,Here Document 可以与非交互式程序和命令一起使用。

1.2 语法格式

命令 << 标记

....
输入内容
......
 
标记

注意事项

  1. 标记可以使用任意的合法字符(通用的字符是EOF

  2. 结尾的标记一定要顶格写,前面不能有任何字符(包括空格)

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

  4. 开头标记前后空格会被省略掉

1.3 示例

示例1:直接把输入的从命令行输出

示例2:输入保存到文件

Shell编程之免交互_第1张图片

示例3:追加输入到文件

Shell编程之免交互_第2张图片

 示例4:创建yum源

Shell编程之免交互_第3张图片

示例5:通过read命令接收输入并打印,输入值是两个EOF标记之间的部分,也就是520,这将作为变量a的值

Shell编程之免交互_第4张图片

 示例6:通过passwd给用户设置密码

Shell编程之免交互_第5张图片

1.4 变量设定(支持变量替换)

1.4.1 在写入文件时要先将变量值换成实际值,再结合cat命令完成写入

案例1:变量替换

[root@localhost /home]#vim test.sh
#!/bin/bash
doc_file="gkd.txt"
i="nanjing"
cat > $doc_file <

案例2:整体赋值给变量,用echo将变量值打印出来

[root@localhost /home]#vim test2.sh
#!/bin/bash
test="you are very good!"
mylife=$(cat <

1.5 格式控制

1.5.1 关闭变量替换的功能

关闭变量替换的功能,按照字符原本的样子输出,不做任何修改或替换

示例1:关闭变量替换

#对标记加单引号,即可关闭变量替换
[root@localhost /home]#aa=$(cat <<'EOF'
> 10
> $a
> EOF
> )
[root@localhost /home]#echo $aa
10 $a
[root@localhost /home]#echo $a
520

1.6 去掉每行之前的 TAB 字符

在第一行的标记前面加“-”,这个表示要抑制各行首Tab的作用

[root@localhost /home]#vim test3.sh
#!/bin/bash
cat <

1.7 多行注释

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

“ : ”代表什么都不做的空命令。中间标记区域的内容不会被执行,会被bash 忽略掉,因此可达到批量注释的效果。

[root@localhost /home]#vim test4.sh

#!/bin/bash
: <

二、Expect 免交互

1.1 概述

expect 是由Don Libes基于Tcl(Tool Command Language )语言开发的,主要应用于自动化交互式操作的场景,是一个免费的编程工具,用来实现自动的交互式任务,而无需人为干预。

说白了,expect就是一套用来实现自动交互功能的软件。

1.2 环境安装

expect 并非是 shell 能够解释的,所以,想要执行它来完成你的脚本,你需要先安装两个软件包,当然,在使用yum的情况下,我们执行这条命令就可以了:

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

1.3 基本命令

1.3.1 脚本解释器

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

#!/usr/bin/expect

1.3.2 spawn

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

spawn passwd root

1.3.3 expect

判断上次输入结果中是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回;

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

用于接收命令执行后的输出,然后和期望的字符串匹配;

1.3.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语句

1.3.5 结束符

expect eof

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

interact

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

注意:expect eof 和interact只能二选一。

1.3.6 set

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

set timeout 20

1.3.7 exp_continue

exp_continue 附加于某个 expect 判断项之后,可以使该项匹配后,还能继续匹配该 expect 判断语句内的其他项

exp_continue 类似于控制语句中 continue 语句,表示允许 expect 继续向下执行指令

例如,将判断交互输出中是否存在 yes/no 或 *password , 如果匹配 yes/no 则输出 yes 并再次执行判断;如果匹配 *password 则输出 123123 并结束该段 expect 语句,操作如下:

 expect
"(yes/no)" {send "yes\r"; exp_ continue; }
"*password" {set timeout 300; send "abc123\r";}

注意:使用exp_continue时,如果跟踪像passwd这样的输入密码后就结束进程的命令,expect{ }外不要再加上expect eof,因为spawn进程结束后会默认向expect发送eof,会导致后面的 expect eof执行报错。

注:表示允许用户进行交互操作,一直保持会话连接

1.3.8 send_user

send_user表示回显命令,相当于echo

1.3.9 接收参数

expect 脚本可以接受从 bash 命令行传递的参数,使用[lindex $argv n] 获得。

其中 n 从0开始,分别表示第一个, 第二个,第三个…参数。

set hostname [lindex $argv 0]   	#相当于 hostname=$1
set password [lindex $argv 1]		#相当于 password=$2

#expect直接执行,需要使用 expect 命令去执行脚本

1.4 用法示例

示例1:ssh免交互登录到远程服务器

[root@localhost /home]#vim expect.sh

#!/usr/bin/expect                   #需要用expect自己的解释器,不要写成bash否则无法识别
spawn ssh [email protected]        #开启一个程序,这个程序是ssh远程登录
expect {                            #捕获内容,当出现password的时候,就会向程序发送密码
         "password:"
        { send "123456\r"; }
}
interact                            #交互,否则会直接退出远程服务器

[root@localhost /home]#chmod +x expect.sh              #需要加执行权限
[root@localhost /home]#./expect.sh  
spawn ssh [email protected]
[email protected]'s password: 
Last login: Mon May 9 16:39:40 2021 from 192.168.10.19

示例2:在对方服务器上进行一下操作后再退出可执行以下脚本

[root@localhost /home]#vim expect.sh

#!/usr/bin/expect
spawn ssh [email protected]
expect {
         "password:"
        { send "123456\r"; }
}
expect "#"                      #当捕获到#的时候
send "ls\r"                     #执行ls命令
send "ifconfig ens33\r"         #执行ifconfig ens33命令
send "exit\r"                   #执行完exit退出登录
expect eof                      #不用进行交互,意味着结束expect程序
 
[root@localhost /home]#chmod +x expect.sh 
[root@localhost /home]#./expect.sh 
spawn ssh [email protected]
[email protected]'s password: 
Last login: Mon May 9 16:35:06 2021 from 192.168.10.19
[root@localhost ~]#ls
[root@localhost ~]#ifconfig ens33
ens33: flags=4163  mtu 1500
        inet 192.168.8.129  netmask 255.255.255.0  broadcast 192.168.8.255
        inet6 fe80::2161:befa:6ffd:c44b  prefixlen 64  scopeid 0x20
        ether 00:0c:29:01:e6:0a  txqueuelen 1000  (Ethernet)
    ......
[root@localhost ~]#exit
登出
Connection to 192.168.10.13 closed.

示例3:引用位置变量

[root@localhost /home]#vim expect1.sh 
#!/usr/bin/expect
set user root
set ip [lindex $argv 0]                #设置第一个位置变量为ip
set pass [lindex $argv 1]              #设置第二个位置变量为登陆密码
spawn ssh $user@$ip
expect {
        "password:"
        { send "$pass\r"; }
}
expect "#"
send "ls\r"
send "exit\r"
expect eof

[root@localhost /home]#chmod +x expect1.sh 
[root@localhost /home]#./expect1.sh 192.168.10.13 123456
spawn ssh [email protected]
[email protected]'s password: 
Last login: Mon May 9 16:38:16 2021 from 192.168.10.19
[root@localhost ~]#ls
[root@localhost ~]#exit
登出
Connection to 192.168.10.13 closed.

 示例4:创建用户并设置用户密码

[root@localhost /home]#vim user.sh

#!/bin/bash
username=$1
useradd $username
/usr/bin/expect <<-EOF
spawn passwd $username
expect {                                 
        "新的 密码"                       #获取的内容和发送的内容不能在同一行否则执行不成功
        { send "123456\r";exp_continue }
        "重新输入新的 密码"
        { send "123456\r"; }
}
EOF

[root@localhost /home]#chmod +x user.sh 
[root@localhost /home]#./user.sh wangwu
spawn passwd wangwu
更改用户 wangwu 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。

总结

借助 expect 处理交互的命令,可以将交互过程如 ssh 登录,ftp 登录等写在一个脚本上,使之自动化完成。

适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率,使用它,你甚至可以仅仅执行一个脚本来完成分布式应用系统的搭建与维护。

 

你可能感兴趣的:(linux,运维)