shell 脚本

  1. 基本监控系统脚本(CPU,内存,IO等)
  2. 后台服务监控、启动、停止脚本、数据备份脚本
  3. 利用grep、sed和awk的复杂用法处理文本
  4. 功能函数编写、主流程设计
  5. 具备复杂功能的大型脚本工具编写

变量替换

语法 说明
${变量名#匹配规则} 从变量开头进行规则匹配,将符合最短的数据删除
${变量名##匹配规则} 从变量开头进行规则匹配,将符合最长的数据删除
${变量名%匹配规则} 从变量尾部进行规则匹配,将符合最短的数据删除
${变量名%%匹配规则} 从变量尾部进行规则匹配,将符合最长的数据删除
${变量名/匹配规则} 变量内容符合旧字符串,则第一个旧字符串会被新字符串取代
${变量名//匹配规则} 变量内容符合旧字符串,则全部旧字符串会被新字符串取代

字符串处理

计算字符串长度

1
2
方法一:${#string}
方法二:expr length $string

获取字符索引位置

1
方法:expr index "$string" substr

获取子串长度

1
方法:expr match "$string" substr

抽取字符串中的子串

1
2
3
4
5
6
7
8
9
10
方法一:

1. ${string:position}
2. ${string:position:length}
3. ${string: -postion} 或者 ${string:(position)}

方法二:
`expr substr $string $position $length`

>使用expr,索引计数从1开始计算;使用`${string:positon:length}`,索引计数从0开始

练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#!/bin/bash
#

string="Bigdata process framework is Hadoop,Hadoop is an open source project"

function print_tips
{
echo "*********************************"
echo "(1) 打印string长度"
echo "(2) 删除字符串中所有的Hadoop"
echo "(3) 替换第一个Hadoop为Mapreduce"
echo "(4) 替换全部的Hadoop为Mapreduce"
echo "*********************************"
}

function len_of_string
{
echo "${#string}"
}

function del_hadoop
{
echo "${string//Hadoop/}"
}

function rep_hadoop_mapreduce_first
{
echo "${string/Hadoop/Mapreduce}"
}

function rep_hadoop_mapreduce_all
{
echo "${string//Hadoop/Mapreduce}"
}

while true
do
echo "【string=$string]"
print_tips
read -p "please input your choice(1|2|3|4|q|Q): " choice

case $choice in
1)
len_of_string
;;
2)
del_hadoop
;;
3)
rep_hadoop_mapreduce_first
;;
4)
rep_hadoop_mapreduce_all
;;
q|Q)
exit
;;
*)
echo "Error, Input only in (1|2|3|4|q|Q)"
;;
esac

echo
done

命令替换

方法

方法一:command
方法二:$(command)

  • 例子1:
    获取系统的所有用户并输出

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #!/bin/bash
    #

    index=1
    for user in `cat /etc/passwd | cut -d ":" -f 1`
    do
    echo "This is $index user : $user"
    index=$(($index+1))
    done
  • 例子2:
    根据系统时间计算今年或明年

    1
    2
    echo "This is $(date +%Y) year"
    echo "This is $(($(date +%Y) + 1)) year "
  • 例子3:
    根据系统时间获取今年还剩下多少星期,已经过了多少星期

    1
    2
    echo "This year have passed $(date +%j) days"
    echo "This year have passed $(($(date +%j)/7)) weeks"
  • 例子4:
    判定nginx进程是否存在,若不存在则自动拉起该进程

    1
    2
    3
    4
    5
    6
    7
    8
    #!/bin/bash
    #

    nginx_process_num=$(ps -ef | grep nginx | grep -v grep | wc -l)
    if [ $nginx_process_num -eq 0 ];then
    #systemctl start nginx
    brew services start nginx
    fi

`` 和 $() 两者是等价的,但推荐使用 $() ,易于掌握;缺点是极少数Unix可能不支持
$(()) 主要用来进行整数运算,包括加减乘除,引用变量前面可以加$,也可以不加$

变量类型

声明变量类型为只读类型

declare -r var="hello"

声明变量类型为整形

declare -i

在脚本中显示定义的函数和内容

declare -f

在脚本中显示定义的函数

declare -F

声明数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
declare -a array
array=("jones" "mike" "kobe" 'jordan')

输出数组内容:
echo ${array[@]} 输出全部内容
echo ${array[1]} 输出下标索引为1的内容

获取数组长度
echo ${#array[@]} 输出数组内元素的个数
echo ${#array[2]} 输出数组下标索引为2的元素的长度

给数组某个下标赋值
array[0] = 'lily'

删除元素
unset array[2] 清空元素

数学运算之expr

1
2
3
4
5
6
7
8
9
10
11
12
13
|
&
>
>=
<
<=
=
!=
+
-
*
/
%

Nginx 监控脚本

1
2
3
4
5
6
7
8
9
10

this_pid=$$
status=`ps -ef | grep nginx | grep -v nginx | grep -v $this_pid &> /dev/null`

if [ $status -eq 0 ];then
echo "Nginx is running well"
else
systemctl start nginx
echo "Nginx is down, Start it ..."
fi