shell函数
在shell环境中,将一些需要重复使用的操作,定义为公共的语句块,即可称为函数(给一堆命令取一个别名)
函数可以使脚本中的代码更加简洁,增强易读性,提高脚本的执行效率

#函数定义格式1
function 函数名 {
	执行的命令1
	执行的命令2
	...省略更多命令
}

#函数定义格式2
函数名() {
	执行的命令1
	执行的命令2
	...省略更多命令
}

#定义函数
[root@localhost ~]# net_ens32() {
ifconfig ens32 | head -2
ifconfig ens32 | grep "RX p"
ifconfig ens32 | grep "TX p"
 }

#调用函数
[root@localhost ~]# net_ens32
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.100  netmask 255.255.255.0  broadcast 192.168.0.255
        RX packets 2337  bytes 178268 (174.0 KiB)
        TX packets 2686  bytes 467232 (456.2 KiB)

#定义函数
[root@localhost ~]# myinfo() {
hostname
cat /etc/redhat-release 
uname -r
free -h
df -h /
}

#调用函数
[root@localhost ~]# myinfo
localhost
CentOS Linux release 7.6.1810 (Core) 
3.10.0-957.el7.x86_64
              total        used        free      shared  buff/cache   available
Mem:           972M        393M        193M         13M        385M        374M
Swap:          2.0G          0B        2.0G
文件系统                 容量  已用  可用 已用% 挂载点
/dev/mapper/centos-root   56G  5.2G   51G   10% /

#fork炸弹
[root@localhost yunwei]# vim fork.sh 
#!/bin/bash
.() {
.|. &
}
.

[root@localhost yunwei]# chmod u+x fork.sh 
[root@localhost yunwei]# ./fork.sh 

脚本中断及退出
break #结束整个循环
continue #结束本次循环,进入下一次循环
exit #退出脚本

#例子

#!/bin/bash
for i in {1..5}
do
        echo $i
done
echo Over

#跳过第三次循环,进入下一次循环


#结束第三次循环,进入下一次循环
#!/bin/bash
for i in {1..5}
do
        [ $i -eq 3 ] && continue
        echo $i
done
echo Over

[root@localhost yunwei]# ./for1.sh 
1
2
4
5
Over


#结束整个循环
#!/bin/bash
for i in {1..5}
do
        [ $i -eq 3 ] && break
        echo $i
done
echo Over

[root@localhost yunwei]# ./for1.sh 
1
2
Over

#直接退出脚本
[root@localhost yunwei]# vim for1.sh
#!/bin/bash
for i in {1..5}
do
        [ $i -eq 3 ] && exit
        echo $i
done
echo Over

[root@localhost yunwei]# ./for1.sh 
1
2

字符串截取
在使用shell脚本完成各种运维任务时,一旦涉及到判断、条件测试等相关操作时往往需要对相关的命令输出进行过滤,提取出符合要求的字符串
字符串截取的常用方法:${变量名:起始位置:长度}
${}截取字符串时,起始位置是从0开始的

[root@localhost yunwei]# phone=13812345678
[root@localhost yunwei]# echo $phone
13812345678

#统计变量的个数
[root@localhost yunwei]# echo ${#phone}
11

#截取变量的前三位,在截取时包含数字本身
[root@localhost yunwei]# echo ${phone:0:3}
138

#截取后四位
[root@localhost yunwei]# echo ${phone:7:4}
5678

#截取中间四位
[root@localhost yunwei]# echo ${phone:3:4}
1234

#截取一个随机的8位密码
[root@localhost yunwei]# vim mima.sh
#!/bin/bash
x=qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789
for i in {1..8}
do
n=$[RANDOM%62]
p=${x:n:1}
pass=$pass$p
done
echo $pass

[root@localhost yunwei]# ./mima.sh 
42iVW9Ba
[root@localhost yunwei]# ./mima.sh 
XuEcVGoR

字符串替换

  • 只替换第一个匹配的结果:${变量名/xx/yy}
  • 替换全部匹配的结果:${变量名//xx/yy}
#只替换匹配到的第一个字符
[root@localhost yunwei]# echo $phone
13812345678

#将匹配到的第一个3替换成4
[root@localhost yunwei]# echo ${phone/3/4}
14812345678  

#将匹配到的所有3替换成4
[root@localhost yunwei]# echo ${phone//3/4}
14812445678

字符串掐头去尾

  • 从左向右,最短匹配删除:${变量名#*关键词}
  • 从左向右,最长匹配删除:${变量名##*关键词}
  • 从右向左,最短匹配删除:${变量名%关键词*}
  • 从右向左,最长匹配删除:${变量名%%关键词*}
#定义素材
[root@localhost yunwei]# x=`head -1 /etc/passwd`
[root@localhost yunwei]# echo $x
root:x:0:0:root:/root:/bin/bash

#从左到右最短匹配
[root@localhost yunwei]# echo ${x#root}
:x:0:0:root:/root:/bin/bash

#从左到右最短匹配,不加*只匹配最左侧的字串
[root@localhost yunwei]# echo ${x#0}
root:x:0:0:root:/root:/bin/bash

#从左到右最短匹配,加*匹配遇到的第一个字串
[root@localhost yunwei]# echo ${x#*0}
:0:root:/root:/bin/bash

#从左到右最长匹配
[root@localhost yunwei]# echo ${x##0}
root:x:0:0:root:/root:/bin/bash

#从左到右最长匹配
[root@localhost yunwei]# echo ${x##*0}
:root:/root:/bin/bash

#从右到做最短匹配
[root@localhost yunwei]# echo ${x%/bash}
root:x:0:0:root:/root:/bin

#从右到做最短匹配
[root@localhost yunwei]# echo ${x%root*}
root:x:0:0:root:/

#从右向左最长匹配
[root@localhost yunwei]# echo ${x%%root*}

#从右向左最短匹配
[root@localhost yunwei]# echo ${x%0*}
root:x:0:

#从右向左最长匹配
[root@localhost yunwei]# echo ${x%%0*}
root:x:

#把文件以.doc结尾的扩展名,全部改为.txt
[root@localhost yunwei]# touch {1..100}.doc
[root@localhost yunwei]# ls
100.doc  17.doc  24.doc  31.doc  39.doc  46.doc  53.doc  60.doc  68.doc  75.doc  82.doc  8.doc   97.doc   if2.sh     while.sh
10.doc   18.doc  25.doc  32.doc  3.doc   47.doc  54.doc  61.doc  69.doc  76.doc  83.doc  90.doc  98.doc   if3.sh
11.doc   19.doc  26.doc  33.doc  40.doc  48.doc  55.doc  62.doc  6.doc   77.doc  84.doc  91.doc  99.doc   if4.sh
12.doc   1.doc   27.doc  34.doc  41.doc  49.doc  56.doc  63.doc  70.doc  78.doc  85.doc  92.doc  9.doc    if5.sh
13.doc   20.doc  28.doc  35.doc  42.doc  4.doc   57.doc  64.doc  71.doc  79.doc  86.doc  93.doc  case.sh  mima.sh
14.doc   21.doc  29.doc  36.doc  43.doc  50.doc  58.doc  65.doc  72.doc  7.doc   87.doc  94.doc  for1.sh  ping.sh
15.doc   22.doc  2.doc   37.doc  44.doc  51.doc  59.doc  66.doc  73.doc  80.doc  88.doc  95.doc  fork.sh  user.sh
16.doc   23.doc  30.doc  38.doc  45.doc  52.doc  5.doc   67.doc  74.doc  81.doc  89.doc  96.doc  if1.sh   while1.sh

#字符串去尾方式批量修改文件扩展名
[root@localhost yunwei]# vim file.sh 
#!/bin/bash
for i in `ls *.doc`
do
        mv $i ${i%doc}txt
done

#字符串替换方式批修改文件扩展名
[root@localhost yunwei]# vim file.sh 
#!/bin/bash
for i in `ls *.txt`
do
        mv $i ${i/txt/doc}
done

#截取一个随机的8位数密码
#例子1
pass.sh
#!/bin/bash
X=qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789
N=$[RANDOM%62]
echo ${X:N:1}

./pass.sh

#例子2
#!/bin/bash
X=qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789
for i in {1..8}
do
N=$[RANDOM%62]
echo ${X:N:1}
done

./pass.sh

#例子3
#!/bin/bash
X=qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789
for i in {1..8}
do
N=$[RANDOM%62]
P=${X:N:1}
PASS=$PASS$P
done
echo $PASS

./pass.sh

shell数组
#定义数组方式一:数组名=(值1 值2 值3 .. .. 值n)
[root@localhost yunwei]# x=(11 22 33 44 55 abc)
[root@localhost yunwei]# echo $x
11

#按照下标取值,下标从0起使,0就是数组内的第一个值
[root@localhost yunwei]# echo ${x[0]}
11
[root@localhost yunwei]# echo ${x[0]}
11
[root@localhost yunwei]# echo ${x[1]}
22
[root@localhost yunwei]# echo ${x[2]}
33
[root@localhost yunwei]# echo ${x[3]}
44
[root@localhost yunwei]# echo ${x[4]}
55

#获取数组内所有值
[root@localhost yunwei]# echo ${x[@]}
11 22 33 44 55 abc

#定义数组方式二:数组名[下标]=值
[root@localhost yunwei]# b[0]=aa
[root@localhost yunwei]# b[1]=xx
[root@localhost yunwei]# b[2]=xxoo
[root@localhost yunwei]# echo ${b[0]}
aa
[root@localhost yunwei]# echo ${b[1]}
xx
[root@localhost yunwei]# echo ${b[2]}
xxoo
[root@localhost yunwei]# echo ${b[@]}
aa xx xxoo
[root@localhost yunwei]# echo ${b[*]}
aa xx xxoo

#通过数组下载软件包
[root@localhost script]# vim yum.sh
#!/bin/bash
x=(vsftpd httpd gcc openssl-devel pcre-devel)
for i in ${x[@]}
do
        yum -y install $i
done

正则表达式
正则表达式使用一串符号描述有共同属性的数据
基本正则符号 描述
^ 匹配行首
$ 匹配行尾
[] 集合,匹配集合中的任意单个字符
[^] 对集合取反
. 匹配任意单个字符

  •           匹配前一个字符出现的任意次数
    
#匹配以什么什么开头的行
[root@localhost yunwei]# grep "^root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@localhost yunwei]# grep "^#" /etc/fstab

#匹配以什么什么结尾的行
[root@localhost yunwei]# grep "bash$" /etc/passwd

[root@localhost yunwei]# grep -v "^#" /etc/fstab
[root@localhost yunwei]# grep -v "^#" /etc/fstab | grep -v "^$" 

#集合,匹配集合中的任意单个字符
[root@localhost yunwei]# grep "ro[abcotabcd]" /etc/passwd

#集合,对集合中的任意单个字符取反
[root@localhost yunwei]# grep "ro[^abcotabcd]" /etc/passwd

#匹配任意单个字符
[root@localhost yunwei]# grep "roo." /etc/passwd
[root@localhost yunwei]# grep ".oot" /etc/passwd

[root@localhost yunwei]# grep "w.*" /etc/passwd

#准备素材
[root@localhost yunwei]# vim 1.txt 
a
b
ab
aab
acb
adb
amnb
amnbmnbmnb
aaaabaaaaaaabaaaaaaaaaaaaab
aabb  the  ccdd
abcthe
thexxoo
xxootheooxx

[root@localhost yunwei]# grep "a*b" 1.txt
[root@localhost yunwei]# grep "a.*b" 1.txt
[root@localhost yunwei]# grep ".*b" 1.txt
[root@localhost yunwei]# grep "a.*" 1.txt

#匹配前一个字符至少出现一次以上,\{n,m\}
[root@localhost yunwei]# grep "a\{1,\}" 1.txt

#匹配前一个字符  n 次,\{n\}
[root@localhost yunwei]# grep "o\{2\}" /etc/passwd
[root@localhost yunwei]# grep "a\{2\}" 1.txt

扩展正则符号 描述
() 组合为整体,可以(复制)
| 或者
\b 单词边界

#基本正则用法
[root@localhost yunwei]# grep "a\{2,4\}b" 1.txt

#使用扩展正则时,需要使用egrep命令过滤
[root@localhost yunwei]# egrep "a{2,4}b" 1.txt

#匹配前一个字符至少出现一次以上
[root@localhost yunwei]# egrep "a+" 1.txt

#基本正则实现方式,匹配前一个字符至少出现一次以上
[root@localhost yunwei]# grep "a\{1,\}" 1.txt

#匹配前一个字符出现了0次或一次
[root@localhost yunwei]# egrep "a?b" 1.txt

#基本正则实现方式,匹配前一个字符出现了0次或一次
[root@localhost yunwei]# grep "a\{0,1\}b" 1.txt
[root@thinkmo ~]# egrep 'a{1,2}' 1.txt 

#或者
[root@localhost yunwei]# egrep "ab|acb|aaab" 1.txt

#组合为整体
[root@localhost yunwei]# egrep "(ab)" 1.txt
ab
aab
aaaabaaaaaaabaaaaaaaaaaaaab
[root@localhost yunwei]# egrep "(acb)" 1.txt
acb
[root@localhost yunwei]# egrep "(aaab)" 1.txt

#单词边界
[root@localhost yunwei]# grep "the" 1.txt
aabb  the  ccdd
abcthe
thexxoo
xxootheooxx
[root@localhost yunwei]# egrep "\bthe\b" 1.txt
aabb  the  ccdd
[root@localhost yunwei]# egrep "\bthe" 1.txt
aabb  the  ccdd
thexxoo
[root@localhost yunwei]# egrep "the\b" 1.txt
aabb  the  ccdd
abcthe
上一篇 下一篇