一、免交互应用
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.
[email protected]'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.
[email protected]'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
版权归原作者 Fang_Qianling 所有, 如有侵权,请联系我们删除。