文章目录
参考书籍:《Linux Shell核心编程指南》——丁明一
一、花括号{}
注意:花括号不可以被引号引用
echo {a..h}
echo {1..9}
echo {1..9..2} #1到9,步长为2
mkdir -p test/{aa,bb}
cp /etc/hosts{,.bak} #利用扩展,备份文件
mv /etc/hosts.bak{,hosts_bak} #重命名
二、波浪号~
波浪号在Shell脚本中默认代表当前用户的家目录
echo ~ #显示当前用户的家目录
ls ~devops #查看devops用户的家目录
~+表示当前工作目录,~-表示上一个工作目录
三、变量替换
3.1.获取变量的值
a=123
echo ${a}
3.2.变量测试
test的值未定义,则返回关键字123,并赋值给变量test,通常用于给变量设置默认值
实现脚本的报错功能,判断一个变量是否有值,没有值或者值为空时就可以返回特定的报错信息,退出状态码为非0
echo ${input:?‘没有输入变量的值’}
与前面相反的示例,当变量没有定义或者为空时,返回空;当变量有值且非空时,返回关键字
设置key=123后,返回关键字value
3.3.字符串切割与掐头去尾
注意:这几种对变量的替换方式,都不会改变变量自身的值
[root@localhost tmp]# value="hello world"
[root@localhost tmp]# echo ${value:2} #从位置2截取到末尾,位置默认从0开始
llo world
[root@localhost tmp]# echo ${value:2:3} #从位置2开始,截取后面3个字符
llo
使用#号可以掐头,使用%号可以去尾
[root@localhost ~]# value="192.168.1.2:5000/root/nginx:1.16"
[root@localhost ~]# echo ${value#*:} #匹配第一个:及其左边的所有内容并删除
5000/root/nginx:1.16
[root@localhost ~]# echo ${value##*:} #掐头最长匹配,删除最后一个:号及其左边的所有内容
1.16
[root@localhost ~]# echo ${value%:*} #从右边开始匹配
192.168.1.2:5000/root/nginx
[root@localhost ~]# echo ${value%%:*} #去尾最长匹配
192.168.1.2
3.4.变量内容的统计与替换
[root@localhost ~]# echo ${!U@} #列出以U开头的所有变量
UID USER
[root@localhost ~]# array1=(11 22 33) #定义普通数组
[root@localhost ~]# echo ${!array1[@]} #返回数组下标
0 1 2
[root@localhost ~]# key="hello world"
[root@localhost ~]# echo ${#key} #统计变量长度
11
[root@localhost ~]# phone=1231121
[root@localhost ~]# echo ${phone/1/x} #将1替换为x,仅替换第一个
x231121
[root@localhost ~]# echo ${phone//1/x} #把所有的1替换为x
x23xx2x
[root@localhost ~]# word="i love you"
[root@localhost ~]# echo ${word^} #将首字母替换为大写
I love you
[root@localhost ~]# echo ${word^^} #将所有字母替换为大写
I LOVE YOU
[root@localhost ~]# echo ${word^o} #将第一个o替换为大写,但并未生效,只能匹配第一个字母,而第一个字母是i
i love you
[root@localhost ~]# echo ${word^^o} #将所有o替换为大写
i lOve yOu
[root@localhost ~]# echo ${word^^[ilo]} #将所有字母i、l、o替换为大写
I LOve yOu
[root@localhost ~]# test="HELLO WORLD"
[root@localhost ~]# echo ${test,} #将首字母替换为小写
hELLO WORLD
[root@localhost ~]# echo ${test,,} #将所有字母替换为小写
hello world
[root@localhost ~]# echo ${test,,[HL]} #将所有H、L替换为小写
hEllO WORlD
四、命令替换
可以通过$(命令)或者`命令`实现,推荐使用$(命令),该方式支持嵌套的命令替换
[root@localhost ~]# echo "系统当前登录人数:$(who | wc -l)"
系统当前登录人数:1
五、算术替换
算术替换扩展的格式为$(()),也可以使用$[],算术扩展支持嵌套。
[root@localhost ~]# echo $[2+3]
5
[root@localhost ~]# echo $[2*3]
6
[root@localhost ~]# echo $[5-2]
3
[root@localhost ~]# echo $[20/4]
5
[root@localhost ~]# echo $[20%6]
2
[root@localhost ~]# echo $[2**3]
8
六、进程替换
命令替换
是把一个命令的输出结果
返回并且赋值给变量,而进程替换
则是把进程的返回结果
通过文件描述符
的方式传递给另一个进程。
语法:<(命令)或者>(命令)
一旦使用了进程替换功能,系统将会在/dev/fd目录下创建文件描述符文件,通过该文件描述符将进程的输出结果传递给其他进程。
示例一
解释:
<(who)会将who命令产生的结果保存到/dev/fd/63
这个文件描述符中,并将该文件描述符作为wc -l命令的输入参数,最终wc -l<(who)的输出结果说明在/dev/fd/63这个文件中包含1行内容。
需注意:
文件描述符是动态生成的,所以当进程执行完毕,再使用ls查看该文件描述符时会提示没有该文件
示例二
将多个进程的输出结果传递给一个进程作为其输入参数;每个进程替换都会创建一个文件描述符
paste <(cut -d: -f1 /etc/passwd) <(cut -d: -f2 /etc/shadow)
提取/etc/passwd的第一列和/etc/shadow中的第二列,通过paste命令将数据合并为一个文件信息。
paste命令会逐行读取多个文件的内容并将多个文件合并
示例三
[root@localhost tmp]# touch {a,b,c}.sh
[root@localhost tmp]# touch {1,2,3}.conf
[root@localhost tmp]# ls | tee >(grep sh$ >sh.log) >(grep conf$ > conf.log)
将sh结尾的文件名重定向到sh.log文件,将conf结尾的文件名重定向到conf.log文件
七、单词切割
单词切割也叫分词,使用IFS变量进行分词处理。如果没有自定义IFS,则默认值为空格、Tab制表符和换行符
八、路径替换
set -f可以禁用路径替换,禁用后Bash不会在路径和文件名中搜索*、?和[符号
使用shopt命令时开启了nocaseglob选项
,则Bash在进行模式匹配时不区分大小写
,默认区分大小写。
shopt命令开启extglob选项
,可以让Bash支持扩展通配符
,默认开启
shopt -s开启特定的Shell属性,shopt -u关闭特定的Shell属性
[root@localhost tmp]# touch {a,A}.txt
[root@localhost tmp]# ls a* #区分大小写
a.txt
[root@localhost tmp]# shopt -s nocaseglob #设置不区分大小写
[root@localhost tmp]# ls a*
a.txt A.txt
[root@localhost tmp]# shopt -u nocaseglob #关闭忽略大小写属性
[root@localhost tmp]# shopt nocaseglob
nocaseglob off