Expect交互工具与字符处理

目录

一、免交互应用

1.  Here Document

1.1 定义与语法

1.2 注意事项

1.3 eof

1.4 tee

2. expect

2.1 定义与格式

2.2 expect基本命令

2.3 interact与expect eof区别演示(免交互ssh主机)

2.4 批量远程新建用户

二、字符处理

1. 字符串切片

1.1 基于偏移量取字符

1.2 基于模式取子串

2. 查找替换

3. 查找删除

4. 大小写转换


一、免交互应用

1.  Here Document

1.1 定义与语法

Here Document 是标准输入的一种替代品,使用I/O重定向的方式将命令列表提供给交互式程序 ,可以帮助脚本开发人员不必使用临时文件来构建输入信息,而是直接就地生产出一个文件并用作命令的标准输入,Here Document 可以与非交互式程序和命令一起使用。

语法格式:

命令  <<  标记
....
......
标记

1.2 注意事项

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

1.3 eof

示例:

使用Here Document结合重定向符号>或>>来将多行文本重定向到文件。

[root@localhost ~]# cat > file.txt << eof
> 1
> 2
> eof
[root@localhost ~]# cat file.txt 
1
2

在上面的示例中,cat > file.txt 表示将输入重定向到 file.txt 文件中。<< oef 表示开始 Here Document,eof 表示结束 Here Document。文本块中的内容会被作为输入传递给 cat 命令,并写入到 file.txt 文件中。当然 cat > file.txt << eof 也可以写成 cat << eof > file.txt。

注意也可以写成<< EOF,同时结束也要写EOF;如果不指定文件,结束后内容将打印在当前屏幕上。

如果你想追加文本到文件而不是覆盖原有内容,可以使用重定向符号 >>

[root@localhost ~]# cat >> file.txt << eof
> a
> b
> eof
[root@localhost ~]# cat file.txt 
1
2
a
b

cat >> file.txt 表示将输入追加到 file.txt 文件中,而不是覆盖原有内容。

可以根据需要自由选择文件名和分隔符。确保开始和结束的分隔符(大小写)相同,并且没有特殊含义。注意,如果结束符eof后存在空格,将没有结束功能,默认为文本内容。

应用:

使用 wc -l 命令后面直接跟文件名就可以统计文件内有多少行内容,将要统计的内容置于标记“EOF” 之间,直接将内容传给 wc -l 来统计。

[root@localhost opt]# vim wc.sh
#!/bin/bash
wc -l << EOF
line 1
line 2
EOF
[root@localhost opt]# bash wc.sh 
2

使用 passwd 命令设置密码,EOF 标记之间的两行是输入的密码和确认密码,两行内容必须保持一致,否则密码设置不成功。此脚本执行后不会输出任何信息,可另开一个终端登录用户,输入新修改的密码来验证密码是否修改正确。

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

Here Document 变量设定:

Here Document 也支持使用变量,如果标记之间有变量被使用,会先替换变量值。如果想要将一些内容写入文件,除了常规的方法外,也可以使用 Here Document。如果写入的内容中包含变量,在写入文件时要先将变量替换成实际值,在结合 cat 命令完成写入。

[root@localhost opt]# name=zhangsan;age=20
[root@localhost opt]# cat << eof
> Name=$name
> Age=$age
> eof
Name=zhangsan
Age=20

定义了两个变量:name 和 age。然后,使用 Here Document 将包含这些变量值的文本传递给 cat 命令。 如果希望在Here Document中保留变量的字面值而不进行替换,可以使用单引号或双引号来括住 Here Document 的开始标记,即 cat << 'eof',在这种情况下,输出将保留 $name 和 $age 作为字面文本,而不会被替换为变量的实际值。

1.4 tee

tee 命令将标准输入复制到每个指定文件,并显示到标准输出。相较于 cat >,tee 后面可以直接跟文件名,不需要重定向直接输出。当需要追加内容时,需要使用-a选项。

[root@localhost opt]# tee file.txt << eof
> 1
> 2
> eof
1
2
[root@localhost opt]# cat file.txt 
1
2

2. expect

2.1 定义与格式

是建立在tcl(tool command language)语言基础上的一个工具,它不同于 bash,常被用于进行自动化控制和测试,解决 shell 脚本中交互的相关问题。工具需要安装。

格式:

expect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]

2.2 expect基本命令

① 脚本解释器:expect 脚本中首先引入文件,表明使用的是哪一种shell。expect的为:/usr/bin/expect

② spawn命令:用于捕捉关键词,后面常跟一个linux执行命令

③ expect命令:用于判断上层捕捉输出的结果是否有指定字符,有则立即返回,没有则默认等待10s

④ exp_continue命令:expect多分支判断时使用

⑤ send命令:expect命令判断完成需要返回时,发送需要交互的指令,想要传递给电脑的文字或字符,该命令不能自动回车换行,\n和\r是回车

⑥ set命令:可用于设置变量、设置expect超时时间,默认是10s,例set time out 30

⑦ set设置位置变量:set password  [lindex $argv 0] ,设置时从0开始,执行脚本时在脚本后跟参数即可

⑧ 结束符:(1) expect eof 结束并返回原来环境,原来主机

                   (2) interact 结束但是不会返回原来的地方,保持当前状态,当前主机

示例:

[root@localhost opt]# expect
expect1.1> expect "fql" {send "hi"}
fql
hiexpect1.2>
# > expect捕捉屏幕上的输出,只要出现“hi”,发送后面的语句

 应用:免交互传输文件,远程拷贝

[root@localhost opt]# vim test
#!/usr/bin/expect
spawn scp /etc/passwd 192.168.190.101:/opt
#监控scp命令,出现scp命令开始捕捉屏幕内容
expect {
        "yes/no" {send "yes\n";exp_continue}
        "password" {send "123123\n";}
}
#捕捉屏幕上的关键字,出现yes/no,输入yes。exp_continue代表继续捕捉password,出现password 输入密码;\n\r回车
expect eof
#代表结束

[root@localhost ~]# expect test
spawn scp /etc/passwd 192.168.190.101:/opt
The authenticity of host '192.168.190.101 (192.168.190.101)' can't be established.
ECDSA key fingerprint is SHA256:aIqKteFz37bh8tOF7A07YElsVqfHgBSbxwkKXK9dfks.
ECDSA key fingerprint is MD5:9c:5a:7f:ec:d9:0c:2a:b2:9d:9e:03:77:f3:87:36:d4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.190.101' (ECDSA) to the list of known hosts.
root@192.168.190.101's password: 
passwd                                                          100% 2101   722.5KB/s   00:00 

192.168.190.101
[root@localhost opt]# ll
总用量 4
-rw-r--r--. 1 root root 2101 1月  31 16:36 passwd

2.3 interact与expect eof区别演示(免交互ssh主机

#!/usr/bin/expect
spawn ssh 192.168.190.101
expect {
        "yes/no" {send "yes\n";exp_continue}
        "password" {send "123123\n";}
}
expect eof
#interact

[root@localhost ~]# expect test1
spawn ssh 192.168.190.101
The authenticity of host '192.168.190.101 (192.168.190.101)' can't be established.
ECDSA key fingerprint is SHA256:aIqKteFz37bh8tOF7A07YElsVqfHgBSbxwkKXK9dfks.
ECDSA key fingerprint is MD5:9c:5a:7f:ec:d9:0c:2a:b2:9d:9e:03:77:f3:87:36:d4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.190.101' (ECDSA) to the list of known hosts.
root@192.168.190.101's password: 
Last login: Wed Jan 31 16:37:35 2024 from 192.168.190.1
[root@localhost ~]# [root@localhost ~]#                 
#默认10秒钟返回
如果配置改为interact,则不会返回

2.4 批量远程新建用户

[root@localhost opt]# vim passwd
#!/bin/bash
ip="192.168.190"
hostlist="
101
102
"
pass=123123

for i  in $hostlist
do
/usr/bin/expect << EOF
spawn ssh ${ip}.${i}
expect {
        "yes/no"    {send "yes\r";exp_continue}
        "password"  {send "$pass\r"}
}
expect "*]#" { send "useradd test\n" }
expect "*]#" { send "echo 123123 | passwd --stdin test\r" }
expect "*]#" { send "exit\r" }

expect eof
EOF
done
[root@localhost opt]# bash passwd

192.168.190.101:
[root@localhost ~]# id test
uid=1001(test) gid=1001(test) 组=1001(test)
192.168.190.102:
[root@localhost ~]# id test
uid=1001(test) gid=1001(test) 组=1001(test)

二、字符处理

1. 字符串切片

1.1 基于偏移量取字符

取字符串的长度

${#var}:返回字符串变量var的字符的长度,一个汉字算一个字符

[root@localhost opt]# str=`echo {a..z} | tr -d " "`
[root@localhost opt]# echo ${#str}             #str变量里一共有26个字符
26
[root@localhost opt]# str=123你好
[root@localhost opt]# echo ${#str}
5

 跳过左边的字符

${var:offset}
#返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到最后的部分,offset的取值在0 到 ${#var}-1 之间(bash4.2后,允许为负值)
${var:offset:number}
#返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,长度为number的部分

[root@localhost opt]# echo ${str}
abcdefghijklmnopqrstuvwxyz
[root@localhost opt]# echo ${str:2:3}     #跳过前两个往后取三个
cde
[root@localhost opt]# echo ${str: -2}     #取后两个
yz

 掐头去尾

${var:offset:-length}
#从最左侧跳过offset字符,一直向右取到距离最右侧lengh个字符之前的内容,即:掐头去尾

[root@localhost opt]# echo ${str:3:-3}    #去掉前后三个,取中间
defghijklmnopqrstuvw

取倒数的范围

${var: -length:-offset}
#先从最右侧向左取到length个字符开始,再向右取到距离最右侧offset个字符之间的内容,注意:-length前空格,并且length必须大于offset

[root@localhost opt]# echo ${str: -5:-3}
vw                                         #倒数5个到,倒数3个

1.2 基于模式取子串

删左留右

${var#*word}
#其中word可以是指定的任意字符,自左而右,查找var变量所存储的字符串中,第一次出现的word, 删除字符串开头至第一次出现word字符串(含)之间的所有字符,即懒惰模式,以第一个word为界删左留右

#同上,贪婪模式,不同的是,删除的是字符串开头至最后一次由word指定的字符之间的所有内容,即贪婪模
式,以最后一个word为界删左留右
${var##*word}

[root@localhost ~]# url="http://www.baidu.com/index.html"
[root@localhost ~]# echo ${url#*/}
/www.baidu.com/index.html
#慵懒模式。从左边开始匹配,遇到/就把/左边的都删除包括/本身
[root@localhost ~]# echo ${url##*/}  
index.html  
#贪婪模式。一直匹配到最后一个/

删右留左

${var%word*}
#其中word可以是指定的任意字符,功能:自右而左,查找var变量所存储的字符串中,第一次出现的word, 删除字符串最后一个字符向左至第一次出现word字符串(含)之间的所有字符,即懒惰模式,以从右向左的第一个word为界删右留左
${var%%word*}
#同上,只不过删除字符串最右侧的字符向左至最后一次出现word字符之间的所有字符,即贪婪模式,以从右向左的最后一个word为界删右留左

[root@localhost ~]# url="http://www.baidu.com:8080/index.html"
[root@localhost ~]# echo ${url%:*}
http://www.baidu.com
[root@localhost ~]# echo ${url%%:*}
http

2. 查找替换

${var/pattern/substr}
${变量/搜索的字符串/修改的字符串}
#查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substr替换之

[root@localhost ~]# user=`grep fql /etc/passwd`
[root@localhost ~]# echo ${user}
fql:x:1000:1000:fql:/home/fql:/bin/bash
[root@localhost ~]# echo ${user/fql/aaa}
aaa:x:1000:1000:fql:/home/fql:/bin/bash

 ${var//pattern/substr}
#查找var所表示的字符串中,所有能被pattern所匹配到的字符串,以substr替换之

[root@localhost ~]# echo ${user//fql/aaa}
aaa:x:1000:1000:aaa:/home/aaa:/bin/bash

${var/#pattern/substr}
#查找var所表示的字符串中,行首被pattern所匹配到的字符串,以substr替换之
在此处#代表开头,不支持贪婪模式

[root@localhost ~]# echo ${user/#fql/aaa}
aaa:x:1000:1000:fql:/home/fql:/bin/bash

${var/%pattern/substr}
#查找var所表示的字符串中,行尾被pattern所匹配到的字符串,以substr替换之
在此处 % 代表结尾,不支持贪婪模式

[root@localhost ~]# echo ${user/%bash/nologin}
fql:x:1000:1000:fql:/home/fql:/bin/nologin

3. 查找删除

${var/pattern}
#删除var表示的字符串中第一次被pattern匹配到的字符串

[root@localhost ~]# user=`grep fql /etc/passwd`
[root@localhost ~]# echo ${user/fql}
:x:1000:1000:fql:/home/fql:/bin/bash

${var//pattern}
删除var表示的字符串中所有被pattern匹配到的字符串

[root@localhost ~]# echo ${user//fql}
:x:1000:1000::/home/:/bin/bash

${var/#pattern}
删除var表示的字符串中所有以pattern为行首匹配到的字符串

[root@localhost ~]# echo ${user/#fql}
:x:1000:1000:fql:/home/fql:/bin/bash

${var/%pattern}
删除var所表示的字符串中所有以pattern为行尾所匹配到的字符串

[root@localhost ~]# echo ${user/%bash}
fql:x:1000:1000:fql:/home/fql:/bin/

4. 大小写转换

${var^^}:把var中的所有小写字母转换为大写
${var,,}:把var中的所有大写字母转换为小写

[root@localhost ~]# a=aBc
[root@localhost ~]# echo ${a^^}
ABC
[root@localhost ~]# echo ${a,,}
abc
  • 25
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值