Shell编程之免交互

目录

[1、Here Document免交互](#1、Here Document免交互)

[(1)Here Document 概述](#(1)Here Document 概述)

(2)免交互执行命令

1)免交互read赋值

2)免交互修改密码

3)免交互统计行数

4)免交互创建文件并编辑文件内容

5)Shell脚本变量替换

6)忽略制表符

7)多行注释

(3)tee命令

2、expect免交互

(1)基本命令

1)声明解释器

2)接受位置参数传入

3)spawn

4)expect

5)send

6)结束符

7)set

8)exp_continute

9)send_user

(2)执行模式

1)直接执行

2)嵌入执行模式

3、实例

(1)普通用户切换root用户

(2)ssh免交互登录


1、Here Document免交互

(1)Here Document 概述

使用I/O重定向的方式将命今列表提供给交互式程序
标准输入的一种替代品

语法格式

命令 <<标记

...

...

标记

Here Document 使用注意事项

  • 标记可以使用任意合法字符EOF
  • 结尾的标记一定要顶格写,前面不能有任何字符
  • 结尾的标记后面也不能有任何字符(包括空格
  • 开头标记前后的空格会被省略掉

(2)免交互执行命令

1)免交互read赋值

正常通过read命令赋值

[root@zx3 ~]# read i
scj  like dancing
[root@zx3 ~]# echo $i
scjlike dancing
[root@zx3 ~]#

免交互

[root@zx3 ~]# read a<<EOF
> scj like xiaojiejie
> EOF
[root@zx3 ~]# echo $a
scj like xiaojiejie
[root@zx3 ~]#

2)免交互修改密码

正常修改密码

[root@zx3 ~]# passwd zhangsan
更改用户 zhangsan 的密码 。
新的 密码:
无效的密码: 密码少于 7 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
[root@zx3 ~]#

免交互

[root@zx3 ~]# passwd zhangsan <<EOF
> abc1234
> abc1234
> EOF
更改用户 zhangsan 的密码 。
新的 密码:无效的密码: 密码未通过字典检查 - 过于简单化/系统化
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。
[root@zx3 ~]#

3)免交互统计行数

[root@zx3 ~]# wc -l <<EOF
> a
> b
> c
> d
> e
> f
> g
> EOF
7
[root@zx3 ~]#

4)免交互创建文件并编辑文件内容

5)Shell脚本变量替换

默认情况下EOF中间的内容支持变量的替换;如果要关闭变量的替换,开头标记要用 '' 括起来,即 <<'EOF'或者用"\"

(1)

(2)

6)忽略制表符

7)多行注释

(3)tee命令

tee file 等于重定向输入

2、expect免交互

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

(1)基本命令

yum -y install expect

1)声明解释器

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

#!/usr/bin/expect

2)接受位置参数传入

expect 脚本可以接受从bash命令行传递的参数,使用[lindex $argv n]获得。其中n从0开始,分别表示第一个,第二个,第三个....参数。

set 变量名 [lindex $argv 0]     #0代表执行脚本时后面跟的第一个位置参数,第二个位置参数用 1 表示,依此类推

3)spawn

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

spawn passwd root

4)expect

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

5)send

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

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

方式二

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

方式三

expect支持多个分支

expect					#只要匹配了其中一个情况,执行相应的send语句后退出该expect语句
{
"密码1" {send "abc123\r"}
"密码2" {send "123456\r"}
"密码3" {send "123123\r"}
}

6)结束符

expect eof

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

interact

执行完成后保持交互状态,把控制权交给控制台,会停留在目标终端而不会退回到原终端,这个时候就可以手工操作了,interact后的命令不起作用,比如interact后添加exit,并不会退出root用户。而如果没有interact则登录完成后会退出,而不是留在远程终端上。
使用interact会保持在终端而不会退回到原终端,比如切换到root用户,会一直在root用户状态下;比如ssh到另一服务器,会一直在目标服务器终端,而不会切回的原服务器。

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

7)set

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

set timeout 30

8)exp_continute

exp_continue 附加于某个 expect 判断项之后,可以使该项被匹配后,还能继续匹配该 expect 判断语句内的其他项。exp_continue 类似于控制语句中的 continue 语句。表示允许 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 执行报错

9)send_user

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

(2)执行模式

1)直接执行

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

su切换用户
#!/usr/bin/expect
#设置超时时间
set timeout 5
#参数传入
set username [lindex $argv 0]
set password [lindex $argv 1]
#开始追踪命令
spawn su $username
#免交互执行,捕捉信息并匹配
expect "密码"
send "$password\r"
expect "*]#"
send_user "ok"
#把控制权交给控制台
interact
#expect eof

2)嵌入执行模式

将 expect 过程融入 Shell 当中,方便执行和处理。像ssh、su这种会切换环境的交互式命令一般不建议使用嵌入执行模式。

#!/bin/bash
user=$1
password=$2
#非交互命令放在expect外面
useradd $user
#开始免交换执行
/usr/bin/expect <<-EOF		#expect 开始标志
spawn passwd $user 			#开启一个进程跟踪 passwd 命令,expect 只能捕捉该进程信息

expect "新的*" 				
send "${password}\r" 		
expect "重新*" 	
send "${password}\r" 		
expect eof				
EOF

3、实例

(1)普通用户切换root用户

#!/bin/expect
spawn su root
expect "密码" {send "abc123\r"}
expect "*]#" {send_user "root用户切换成功"}
interact

(2)ssh免交互登录

#!/usr/bin/expect
set a [lindex $argv 0]
set b [lindex $argv 1]
spawn ssh $a
expect {
    "Connection refused" {send_user "目标主机访问被拒绝\n"}
    "No route to host" {send_user "目标主机没有开机\n"}
    "(yes/no)" {send "yes\r"; exp_continue; }
    "*password:" {send "$b\r"}

}
interact
相关推荐
C++忠实粉丝25 分钟前
Linux环境基础开发工具使用(2)
linux·运维·服务器
康熙38bdc1 小时前
Linux 环境变量
linux·运维·服务器
存储服务专家StorageExpert1 小时前
DELL SC compellent存储的四种访问方式
运维·服务器·存储维护·emc存储
hakesashou2 小时前
python如何比较字符串
linux·开发语言·python
Ljubim.te2 小时前
Linux基于CentOS学习【进程状态】【进程优先级】【调度与切换】【进程挂起】【进程饥饿】
linux·学习·centos
cooldream20092 小时前
Linux性能调优技巧
linux
大G哥2 小时前
记一次K8S 环境应用nginx stable-alpine 解析内部域名失败排查思路
运维·nginx·云原生·容器·kubernetes
长天一色2 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
醉颜凉2 小时前
银河麒麟桌面操作系统修改默认Shell为Bash
运维·服务器·开发语言·bash·kylin·国产化·银河麒麟操作系统
QMCY_jason3 小时前
Ubuntu 安装RUST
linux·ubuntu·rust