当前位置: 首页 > news >正文

今天继续学习shell脚本

ssh服务

通过ssh服务进行远程连接

格式为:服务类型 用户名@要连接的IP地址 例如:ssh  root@192.168.60.145

宿主机和虚拟机之间的通信原理,互联采用的虚拟网卡进行互联,注意看那个虚拟网卡要先看虚拟机设置是网卡信息。

互联步骤(宿主机与虚拟机):利用win+r打开命令提示符,在进行ssh root@192.168.60.145(虚拟机IP) , yes,进行互联,所产生的ssh有关信息就放在了c盘用户下的sh文件夹的knowns-hostname中

虚拟机之间互联也是采用该命令。

一.Shell中的expect


expect 将交互式的操作,利用脚本的形式,转为非交互是的操作。(本质上就是将交互式的内容逐一写入脚本中,使其实现通过脚本就能自动运行)

expect 的安装
yum install -y expect

如何使用expect


通过上面expect的工作流程,我们可以认识到,expect的内置命令:spawn(启动交互进程)、expect(获取关键字)、send(发送响应内容)等非常重要,所以下面我们先来了解下它们的使用。

spawn:由它进行代替交互

expect: 在交互时所产生的步骤关键点

send:发送在交互的时候所输入的内容

spawn命令


spawn作用:启动新的产生交互的进程

下面我们以修改一个已存在账户的密码为例,举例如下:

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

基于expect交互界面做法

[root@localhost ~]# expect
expect1.2> spawn passwd tom
spawn passwd tom
11145
expect1.3> expect "密码: "
更改用户 tom 的密码 。
新的密码: expect1.4> send "123456\r"
expect1.5> expect "密码: "无效的密码: 密码少于 8 个字符
重新输入新的密码: expect1.6> send "123456\r"
expect1.7> expect eofpasswd:所有的身份验证令牌已经成功更新。
expect1.8> exit

其中expect作用:获取从spawn命令执行的命令和程序后产生的交互信息。看看是否匹配,如果匹配,就开始执行expect进程接收字符串。

send命令的主要作用是,在expect命令匹配完指定的字符后,发送指定的字符串给系统程序,在字符中可以支持部分特殊转义符,比如:n(回车)r(换行)t(制表符)等。

下面是上述实验的expect脚本案例:

[root@localhost ~]# vim user_pwd.sh
#!/usr/bin/expect
spawn passwd tom
expect {
"新的密码: " { send "123.com\r"; exp_continue }
"新的密码: " { send "123.com\r" }
eof
}
[root@localhost ~]# ./user_pwd.sh 
spawn passwd tom
更改用户 tom 的密码 。
新的密码: 
无效的密码: 密码少于 8 个字符
重新输入新的密码: 
passwd:所有的身份验证令牌已经成功更新。

利用expect进行非交互式的形式查看另一端口信息:

[root@localhost ~]# vim ssh_login.sh
#!/usr/bin/expect
spawn ssh root@192.168.60.145
expect {
"*yes/no* " { send "yes\r"; exp_continue }
"*password: " { send "q1w2e3@123!!!!!\r" }
eof
}
[root@localhost ~]# ./ssh_login.sh 
spawn ssh root@192.168.60.145Authorized users only. All activities may be monitored and reported.
root@192.168.60.145's password: [root@localhost ~]# 

exp_continue命令


exp_continue命令的主要作用是,如果需要一次匹配多个字符串,那么多次匹配字符串并执行不同的动作中,可以让expect程序实现继续匹配的效果。

send_user命令


send_user命令的作用是:用来打印expect脚本信息,类似shell里的echo命令。

二.expect变量


普通变量

expect中定义普通变量的语法如下:

set为变量名 变量值

puts 进行调取

例如:

set chengshi "beijing"

调取变量的方法是:

puts $变量名

#或者

send_user "$变量名"

expect中位置参数变量

如何向expect脚本中像shell一样传递类似于$0、$1等位置参数,用于接收及控制expect脚本传递位置参数变量呢?

expect是通过如下语法来进行的:

set <变量名称> [lindex $argv <param index> ]

当然,除了基本的位置参数外,expect还支持其它的特殊参数,比如:

$argc 表示传入参数的个数

$argv0 表示当前执行脚本的名称

案例1:

[root@localhost ~]# vim exp_var.sh
#!/usr/bin/expect
set var1 [lindex $argv 0]
puts $var1
[root@localhost ~]# chmod +x exp_var.sh
[root@localhost ~]# ./exp_var.sh 1
1
[root@localhost ~]# ./exp_var.sh 12
12

案例2:

[root@localhost ~]# vim exp_var2.sh 
#!/usr/bin/expect
# Filename: expect_var2.exp
set file1 [lindex $argv 0]
set file2 [lindex $argv 1]
set file3 [lindex $argv 2]
puts "The files are : $file1 $file2 $file3"
puts "The number of files are: $argc"
puts "The expect script name is: $argv0"
[root@localhost ~]# chmod +x exp_var2.sh 
[root@localhost ~]# ./exp_var2.sh 
The files are :   
The number of files are: 0
The expect script name is: ./exp_var2.sh
[root@localhost ~]# ./exp_var2.sh 1.txt
The files are : 1.txt  
The number of files are: 1
The expect script name is: ./exp_var2.sh
[root@localhost ~]# ./exp_var2.sh 1.txt 2.txt
The files are : 1.txt 2.txt 
The number of files are: 2
The expect script name is: ./exp_var2.sh
[root@localhost ~]# ./exp_var2.sh 1.txt 2.txt 3.txt
The files are : 1.txt 2.txt 3.txt
The number of files are: 3
The expect script name is: ./exp_var2.sh

以上脚本也能支持更多变量写入

[root@localhost ~]# vim exp_var.sh 
#!/usr/bin/expect
set var1 [ lindex $argv 0 ]
set var2 [ lindex $argv 1 ]
puts "$var1 \t $var2"
[root@localhost ~]# ./exp_var.sh 1 2
1        2

三.expect中的if条件语句(了解)


[root@localhost ~]# vim expect-if.exp

#!/usr/bin/expect

# Filename: expect-if.exp

if {$argc <= 3} {

puts "The IP numbers <= 3"

} else {

puts "The IP numbers > 3"

}

[root@localhost ~]# chmod +x expect-if.sh

[root@localhost ~]# ./expect-if.sh 192.168.200.{1..3}

The IP numbers <= 3

[root@localhost ~]# ./expect-if.sh 192.168.200.{1..5}

The IP numbers > 3

四.expect中的for条件语句(了解)


{ set i 1 } 定义i的值为1

{ $i <= 10 }循环的条件

{ incr i 1} 制定$i的增量值,必须写在这行的末尾处,默认增量值为1

案例:

[root@localhost ~]# cat expect-for.exp

#!/usr/bin/expect

for { set i 1 } { $i <= 10 } { incr i 1 } {

puts "$i"

}

[root@localhost ~]# expect expect-for.exp

1

2

3

4

5

6

7

8

9

10

五.expect中的while条件语句(了解)


案例:

[root@localhost ~]# vim expect-while.exp

#!/usr/bin/expect

set i 1

while {$i <= 10} {

puts "$i"

sleep 1

incr i 1

}

[root@localhost ~]# expect expect-while.exp

1

2

3

4

5

6

7

8

9

10

六.expect中的常用关键字


eof关键字

就是执行开始和结束时候用的

cat >>file <<OEFrr content rr

timeout关键字

设置超时时间

set timeout -1 -- 永久不超时

set timeout 0 -- 立即执行

set timeout XX -- 设定具体的timeout时间(秒),默认是10秒

七.在shell脚本中执行expect命令


用expect -c 就可以在shell中用expect命令

案例:

方法一(脚本声明为shell,用 -c 调用expect命令,利用-c “” 的形式,但这个不能在openeuler中使用该命令)

#!/bin/bash
for i in [ 192.168.47.177 192.168.47.163 ]
do
expect -c "
spawn ssh root@$i ip a
expect {
"*yes/no*" { send "yes\r";exp_continue }
"*password:" { send "q1w2e3@123!!!!!\r";exp_continue }
}
expect eof
"
done

方法二

[root@localhost ~]# vim test.sh
#!/bin/bash
for i in [ 192.168.47.177 192.168.47.163 ]
do
expect <<EOF
spawn ssh root@$i ip a
expect {
"*yes/no*" { send "yes\r";exp_continue }
"*password:" { send "q1w2e3@123!!!!!\r";exp_continue }
}
EOF
done
[root@localhost ~]# chmod +x test.sh 
[root@localhost ~]# ./test.sh 
missing close-bracketwhile executing
"spawn ssh root@["
spawn ssh root@192.168.60.145 ip a

sed编辑器(对shell脚本的修改)

案例:对cxc脚本中的tom换成join。实现非交互式写入

[root@localhost ~]# sed -i "s/tom/join" cxc.sh

脚本内容改变四剑客:

awk

grep

find

sed

八.正则表达式


分基础正则表达式,扩展正则表达式两种,里面都是含有元字符和普通字符组成的。
元字符含义及用法
\转义字符,用于取消特殊符号的含义,例: \!\n\$
^匹配字符串开始的位置,例:^a^the^#^[a-z]
$匹配字符串结束的位置,例: word$^$匹配空行
.匹配除\n之外的任意的一个字符,例: go.dg..d。如果想要匹配包含\n字符可以使用 [.\n]
*匹配前面子表达式0次或者多次,例: goo*dgo.*d
[list]匹配list列表中的一个字符,例: go[ola]d[abc][a-z][a-z0-9][0-9]匹配任意一位数字
[^list]匹配任意非list列表中的一个字符,例:[^0-9][^A-Z0-9][^a-z]匹配任意一位非小写字母
\{n\}匹配前面的子表达式n次,例: go\{2\}d[0-9]\{2\}匹配两位数字
\{n,\}匹配前面的子表达式不少于n次,例: gol{2,l}d[0-9]\{2,\}匹配两位及两位以上数字
\{n,m\}匹配前面的子表达式n到m次,例 : go\{2,3\}d[0-9]\{2,3\}匹配两位到三位数字
注: egrepawk使用{n}{n,}{n,m}匹配时 {} 前不用加 \

以上为shell脚本支持的,支持的工具为:grep、egrep、sed、awk

以下要用-p来用,支持的工具:grep、egrep、sed、awk,注意grep要配合-E或者-P使用

\w匹配包括下划线的任何单词字符。
\W匹配任何非单词字符。等价于[^A-Za-z0-9_]
\d匹配一个数字字符。
\D匹配一个非数字字符。等价于[^0-9]
\s空白符。
\S非空白符。

grep -E 等价于egrep,都是一样的输出结果

案例:筛选出文本中只用0-9数字信息的

筛选出只有两字符的有关信息,grep -E等价于egrep

[root@localhost ~]# grep '[^0-9]' grep.txt
1561d1as6 da5
56551asd a1
6ad15d1a5da 
56156ada5gsggjtjj
asdafasf
aseefsdfsdfsd
[root@localhost ~]# grep '[0-9]' grep.txt
1561d1as6 da5
56551asd a1
6ad15d1a5da 
56156ada5gsggjtjj
55665659595913156
565656515
54654
[root@localhost ~]# grep '[0-9]\{4\}' grep.txt
1561d1as6 da5
56551asd a1
56156ada5gsggjtjj
55665659595913156
565656515
54654
[root@localhost ~]# egrep '[0-9]{4}' grep.txt
egrep: warning: egrep is obsolescent; using grep -E
1561d1as6 da5
56551asd a1
56156ada5gsggjtjj
55665659595913156
565656515
54654

今日作业

利用chpasswd的功能对其设置脚本实现非交互式批量创建用户及密码
[root@localhost ~]# vim test.sh 
#!/bin/bash
#批量更改用户密码
user=$(cat user_passwd.txt | cut -d ':' -f1)
passwd=$(cat user_passwd.txt | cut -d ':' -f2)for i in $user
doexpect<<EOFspawn passwd $iexpect {"*密码: " { send "$passwd\r"; exp_continue }"*密码: " { send "$passwd\r"; }}
EOF
done
[root@localhost ~]# ./test.sh
spawn passwd user1
更改用户 user1 的密码 。
新的密码: 
无效的密码: 密码少于 8 个字符
重新输入新的密码: 
passwd:所有的身份验证令牌已经成功更新。
spawn passwd user2
更改用户 user2 的密码 。
新的密码: 
无效的密码: 密码少于 8 个字符
重新输入新的密码: 
passwd:所有的身份验证令牌已经成功更新。
spawn passwd user3
更改用户 user3 的密码 。
新的密码: 
无效的密码: 密码少于 8 个字符
重新输入新的密码: 
passwd:所有的身份验证令牌已经成功更新。
spawn passwd user4
更改用户 user4 的密码 。
新的密码: 
无效的密码: 密码少于 8 个字符
重新输入新的密码: 
passwd:所有的身份验证令牌已经成功更新。
spawn passwd user5
更改用户 user5 的密码 。
新的密码: 
无效的密码: 密码少于 8 个字符
重新输入新的密码: 
passwd:所有的身份验证令牌已经成功更新。


文章转载自:

http://PFoEhVI2.xhLpn.cn
http://VSMJFI2i.xhLpn.cn
http://nEfCmiNi.xhLpn.cn
http://mDwiH1aH.xhLpn.cn
http://TuPpYRUx.xhLpn.cn
http://Ogwh79nv.xhLpn.cn
http://FLlIoSVV.xhLpn.cn
http://afGj6uAT.xhLpn.cn
http://KOmxVhL5.xhLpn.cn
http://PkGrv3oV.xhLpn.cn
http://YRUwGV43.xhLpn.cn
http://tGu0r3aQ.xhLpn.cn
http://f3jOz7y4.xhLpn.cn
http://dDbKlENf.xhLpn.cn
http://fh9CcjIv.xhLpn.cn
http://1cjcjePb.xhLpn.cn
http://zFF7JXq4.xhLpn.cn
http://Sw6QS5tB.xhLpn.cn
http://oVoatxRe.xhLpn.cn
http://DVd8D3g4.xhLpn.cn
http://okGiEjSe.xhLpn.cn
http://AZU03DOv.xhLpn.cn
http://69OBX92e.xhLpn.cn
http://o0km81nk.xhLpn.cn
http://8BqYlYbB.xhLpn.cn
http://NkASF1fF.xhLpn.cn
http://momXMH3Q.xhLpn.cn
http://9xG4lCtH.xhLpn.cn
http://0XS5B8sG.xhLpn.cn
http://n5DcaFyj.xhLpn.cn
http://www.dtcms.com/a/374126.html

相关文章:

  • 解决哈希冲突
  • C++算法专题学习:栈相关的算法
  • CentOS部署ELK Stack完整指南
  • 多模态大模型Keye-VL-1.5发布!视频理解能力更强!
  • JAK/STAT信号通路全解析:核心分子、激活与负调控
  • 人工智能知识图谱应用平台国家标准发布实施
  • Chiplet封装革命:路登多芯片同步固晶治具支持异构集成
  • 语法分析:编译器中的“语法警察”
  • python数据分析工具特点分析
  • 高并发场景下的“命令执行”注入绕道记
  • Java创建对象的5种方式
  • Redis+Envoy实现智能流量治理:动态读写分离方案
  • ros2中qos的调优配置
  • 【GPT入门】第65课 vllm指定其他卡运行的方法,解决单卡CUDA不足的问题
  • 网络地址转换(NAT)详解
  • 综合体项目 3D 数字孪生可视化运维管理平台解决方案
  • 平衡车 -- MPU6050
  • 【PyTorch】图像二分类
  • 自动驾驶中的传感器技术39——Radar(0)
  • 【进阶版两种方法 | 题解】洛谷 P4285 [SHOI2008] 汉诺塔 [数学分析递推]
  • DFT学习--文献
  • 多轻量算轻量
  • GITHUB 项目推荐:DAIR.AI 提示词工程指南
  • DAMA数据管理|4数据管理的挑战-价值要度量
  • 【LLM微调2】
  • springboot minio 存储入门与实战
  • RabbitMQ 幂等性, 顺序性 和 消息积压
  • 单片机按键示例功能
  • Enable FIPS in ubuntu (by quqi99)
  • OpenAI的开源王牌:gpt-oss上手指南与深度解析