(转)shell 大型脚本工具开发实战

原文:https://www.cnblogs.com/crazymagic/p/11173162.html

拆分脚本功能,抽象函数

  • 1、function get_all_group 返回进程组列表字符串
  • 2、function get_all_process 返回进程名列表字符串"nginx httpd mysql datanode"
  • 3、function get_process_info 返回进程详细信息列表字符串,详细信息包括:运行状态、PID、CPU、MEM、启动时间 注:该函数可以接收一个参数,参数为进程名称
  • 4、function get_all_process_by_group 返回进程组内的所有进程名称列表字符串

配置文件

process.cfg

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[GROUP_LIST]
WEB
DB
HADOOP
YARN
 
[WEB]
nginx
httpd
 
[DB]
mysql
postgresql
oracle
 
[HADOOP]
datanode
namenode
journalnode
 
[YARN]
resourcemanager
nodemanager

  

功能函数代码 1 (获取进程组列表)

1
sed -n '/\[GROUP_LIST]/,/\[.*\]/p' process.cfg | grep -v "^$" | grep -v "\[.*\]"

使用egrep 优化

1
sed -n '/\[GROUP_LIST]/,/\[.*\]/p' process.cfg | egrep -v "(^$|\[.*\])"

封装函数

app_status.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash
#
# Func: Get Process Status In process.cfg
 
# Define Variables
HOME_DIR="/home/roo/Desktop/shell_code/day9"
CONFIG_FILE="process.cfg"
# 进程本身的pid
this_pid=$$
 
# 获取所有的组
function get_all_group
{
    G_LIST=$(sed -n '/\[GROUP_LIST]/,/\[.*\]/p' $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])")
    echo $G_LIST
}
 
for g in `get_all_group`;do
    echo $g
done

 

执行脚本

1
sh app_status.sh

 

功能函数代码 2 (获取每个进程组中的进程)

app_status.sh

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
#!/bin/bash
#
# Func: Get Process Status In process.cfg
 
# Define Variables
HOME_DIR="/home/roo/Desktop/shell_code/day9"
CONFIG_FILE="process.cfg"
# 进程本身的pid
this_pid=$$
 
# 获取所有的组
function get_all_group
{
    G_LIST=$(sed -n '/\[GROUP_LIST]/,/\[.*\]/p' $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])")
    echo $G_LIST
}
 
#for g in `get_all_group`;do
#    echo $g
#done
 
function get_all_process
{
    for g in `get_all_group`
    do
        P_LIST=`sed -n "/\[$g\]/,/\[.*\]/p" $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])"`
        echo $P_LIST
    done
}
 
echo `get_all_process`

  

执行脚本

1
sh app_status.sh

 

功能函数代码 3 (获取每个进程组中的进程、返回进程详细信息列表字符串,详细信息包括:运行状态、PID、CPU、MEM、启动时间)

1
ps -aux | grep nginx

 

第二列是进程的id第三列是cpu使用率,第四列是内存使用率

功能拆分1 :

get_process_pid_by_name   根据进程的名字获取进程 id  

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
#!/bin/bash
#
# Func: Get Process Status In process.cfg
 
# Define Variables
HOME_DIR="/home/roo/Desktop/shell_code/day9"
CONFIG_FILE="process.cfg"
# 进程本身的pid
this_pid=$$
 
# 获取所有的组
function get_all_group
{
    G_LIST=$(sed -n '/\[GROUP_LIST]/,/\[.*\]/p' $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])")
    echo $G_LIST
}
 
#for g in `get_all_group`;do
#    echo $g
#done
 
function get_all_process
{
    for g in `get_all_group`
    do
        P_LIST=`sed -n "/\[$g\]/,/\[.*\]/p" $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])"`
        echo $P_LIST
    done
}
 
this_pid=$$
function get_process_pid_by_name    # 获取进程的pid
{
    if [ $# -ne 1 ];then
        return 1
    else
        #pids=`ps -ef | grep $1 | grep -v grep | grep -v $this_pid |grep -v $0| awk '{print $2}'`
        pids=`ps -ef | grep $1 | grep -v grep | grep -v $0| awk '{print $2}'`
        echo $pids
    fi
}
 
get_process_pid_by_name $1

执行脚本

1
sh app_status.sh nginx

 

 

功能拆分2 :

get_process_info_by_pid 根据进程 id 获取进程详细信息  

 

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
#!/bin/bash
#
# Func: Get Process Status In process.cfg
 
# Define Variables
HOME_DIR="/home/roo/Desktop/shell_code/day9"
CONFIG_FILE="process.cfg"
# 进程本身的pid
this_pid=$$
 
# 获取所有的组
function get_all_group
{
    G_LIST=$(sed -n '/\[GROUP_LIST]/,/\[.*\]/p' $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])")
    echo $G_LIST
}
 
#for g in `get_all_group`;do
#    echo $g
#done
 
function get_all_process
{
    for g in `get_all_group`
    do
        P_LIST=`sed -n "/\[$g\]/,/\[.*\]/p" $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])"`
        echo $P_LIST
    done
}
 
this_pid=$$
function get_process_pid_by_name    # 获取进程的pid
{
    if [ $# -ne 1 ];then
        return 1
    else
        #pids=`ps -ef | grep $1 | grep -v grep | grep -v $this_pid |grep -v $0| awk '{print $2}'`
        pids=`ps -ef | grep $1 | grep -v grep | grep -v $0| awk '{print $2}'`
        echo $pids
    fi
}
function get_process_info_by_pid    # 获取进行信息
{
    # awk 中引入一个变量
    if [ `ps -ef | awk -v pid=$1 '$2==pid{print}' | wc -l` -eq 1 ];then
        pro_status="RUNNING"
    else
        pro_status="STOPED"
    fi
    pro_cpu=`ps aux | awk -v pid=$1 '$2==pid{print $3}'`
    pro_mem=`ps aux | awk -v pid=$1 '$2==pid{print $4}'`
    pro_start_time=`ps -p $1 -o lstart | grep -v STARTED`
}
 
get_process_info_by_pid $1
 
echo "$pro_status $pro_cpu $pro_mem $pro_start_time"

 

 运行脚本

1
sh app_status.sh 1229

 

功能函数代码 4 

is_group_in_config: 判断输入的组是否在配置文件中

get_all_process_by_group: 根据输入的组输出当前组下的进程名

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#!/bin/bash
#
# Func: Get Process Status In process.cfg
 
# Define Variables
HOME_DIR="/home/roo/Desktop/shell_code/day9"
CONFIG_FILE="process.cfg"
# 进程本身的pid
this_pid=$$
 
# 获取所有的组
function get_all_group
{
    G_LIST=$(sed -n '/\[GROUP_LIST]/,/\[.*\]/p' $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])")
    echo $G_LIST
}
 
#for g in `get_all_group`;do
#    echo $g
#done
 
function get_all_process
{
    for g in `get_all_group`
    do
        P_LIST=`sed -n "/\[$g\]/,/\[.*\]/p" $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])"`
        echo $P_LIST
    done
}
 
this_pid=$$
function get_process_pid_by_name    # 获取进程的pid
{
    if [ $# -ne 1 ];then
        return 1
    else
        #pids=`ps -ef | grep $1 | grep -v grep | grep -v $this_pid |grep -v $0| awk '{print $2}'`
        pids=`ps -ef | grep $1 | grep -v grep | grep -v $0| awk '{print $2}'`
        echo $pids
    fi
}
function get_process_info_by_pid    # 获取进行信息
{
    # awk 中引入一个变量
    if [ `ps -ef | awk -v pid=$1 '$2==pid{print}' | wc -l` -eq 1 ];then
        pro_status="RUNNING"
    else
        pro_status="STOPED"
    fi
    pro_cpu=`ps aux | awk -v pid=$1 '$2==pid{print $3}'`
    pro_mem=`ps aux | awk -v pid=$1 '$2==pid{print $4}'`
    pro_start_time=`ps -p $1 -o lstart | grep -v STARTED`
}
 
function is_group_in_config
{
    # 如果遍历不存在就返回1
    for gn in `get_all_group`;do
        if "$gn" == "$1" ];then
            return
        fi
    done
    return 1
}
 
function get_all_process_by_group
{
    is_group_in_config $1
    if [ $? -eq 0 ];then
        p_list=`sed -n "/\[$1\]/,/\[.*\]/p" $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|^#|\[.*\])"`
        echo $p_list
    else
        echo "GroupName $1 is not in process.cfg"
    fi
}
 
is_group_in_config $1 && echo exist || echo not exist
get_all_process_by_group $1

  

执行脚本

1
sh app_status.sh WEB

 

程序主流程设计及代码实现

app_status.sh 执行有三种情况

  •  1、无参数 列出配置文件中所有进程的运行信息
  •  2、-g GroupName 列出GroupName组内的所有进程
  •  3、process_name1 列出指定进程的运行信息

 

    function get_all_group
    说明:该函数无需输入任何参数:返回配置文件 process.cfg中所有的组信息,例如web,db等

    function get_all_process

        说明:该函数无需输入任何参数:返回配置文件 process.cfg中所有的进程信息

    function get_process_pid_by_name

        说明:该函数接收一个参数,参数为进程名称:返回值是一个PID的列表,可能有一个PID,也可能有多个

    function get_process_info_by_pid

        说明:该函数接收一个参数,参数为进程PID;返回值是一个进程运行信息的列表,列表包含运行状态:CPU占用率、内存占用率、进程运行时间

    function is_group_in_config
        
        说明 :该函数接收一个参数,参数为组的名称;返回值是0或1,0代表该组在配置文件中,1代表该组不在配置文件中

    function get_all_process_by_group
        
        说明:该函数接收一个参数,参数为组名称:返回值是对应组内的所有进程名称列表

    function get_group_by_process_name
        
        说明:该函数接收一个参数,参数是一个进程名称:返回值是一个组名

    function format_print

        说明:该函数接收两个参数,第一个参数为process_name,第二个参数为组名称
        返回值,是针对每一个进程PID的运行信息

    function is_process_in_config
        
        说明:该函数接收一个参数,参数为进程名称;返回值是0或1,0代表该进程在配置文件中,1代表进程不在配置文件中
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/bin/bash
#
# Func: Get Process Status In process.cfg
 
# Define Variables
HOME_DIR=""/home/roo/Desktop/shell_code/day9""
CONFIG_FILE="process.cfg"
# 进程本身的pid
this_pid=$$
 
# 获取所有的组
function get_all_group
{
    G_LIST=$(sed -n '/\[GROUP_LIST]/,/\[.*\]/p' $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])")
    echo $G_LIST
}
 
#for g in `get_all_group`;do
#    echo $g
#done
 
# 获取所有进程
function get_all_process
{
    for g in `get_all_group`   
    do
        P_LIST=`sed -n "/\[$g\]/,/\[.*\]/p" $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])"`
        echo $P_LIST
    done
}
 
# 通过pid获取进程名称
function get_process_pid_by_name
{
    if [ $# -ne 1 ];then
        return 1
    else
        #pids=`ps -ef | grep $1 | grep -v grep | grep -v $this_pid |grep -v $0| awk '{print $2}'`
        pids=`ps -ef | grep $1 | grep -v grep | grep -v $0| awk '{print $2}'`
        echo $pids
    fi
}
 
# 通过pid 获取进程信息
function get_process_info_by_pid
{
    # awk 中引入一个变量
    if [ `ps -ef | awk -v pid=$1 '$2==pid{print}' | wc -l` -eq 1 ];then
        pro_status="RUNNING"
    else
        pro_status="STOPED"
    fi
    pro_cpu=`ps aux | awk -v pid=$1 '$2==pid{print $3}'`
    pro_mem=`ps aux | awk -v pid=$1 '$2==pid{print $4}'`
    pro_start_time=`ps -p $1 -o lstart | grep -v STARTED`
     
    #echo "pro_status=$pro_status"
    #echo "pro_cpu=$pro_cpu"
    #echo "pro_mem=$pro_mem"
    #echo "pro_start_time=$pro_start_time"
}
 
# 判断输入的组是否在配置文件中
function is_group_in_config
{
    # 如果遍历不存在就返回1
    for gn in `get_all_group`;do
        if "$gn" == "$1" ];then
            return 0
        fi       
    done
    echo "Group $1 is not in process.cfg"
    return 1
}
 
# 判断进程是否在配置中
function is_process_in_config
{
    for pn in `get_all_process`;do
        if [ $pn == $1 ];then
            return
        fi
    done
    echo "Process $1 is not in process.cfg"
    return 1
}
 
# 通过组名获取组下所有的进程
function get_all_process_by_group
{
    # 判断输入的组名是否在group中
    is_group_in_config $1
    if [ $? -eq 0 ];then
        p_list=`sed -n "/\[$1\]/,/\[.*\]/p" $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|^#|\[.*\])"`
        echo $p_list
    else
        echo "GroupName $1 is not in process.cfg"
    fi   
}
 
# 通过进程名称获取所在的组
function get_group_by_process_name
{
    for gn in `get_all_group`;do
        for pn in `get_all_process_by_group $gn`;do
            #echo "pn=$pn"
            if [ $pn == $1 ];then
                echo "$gn"
            fi
        done   
    done
}
 
 
 
#if [ ! -e $HOME_DIR/$CONFIG_FILE ];then
#    echo "$CONFIG_FILE is not exists..please check.."
#fi
 
#is_group_in_config $1 && echo "exists" || echo "not exists"
 
#get_all_process_by_group $1
 
function format_print
{
    ps -ef | grep $1 | grep -v grep | grep -v $this_pid &> /dev/null
    if [ $? -eq 0 ];then
        pids=`get_process_pid_by_name $1`
        #echo "pids=$pids"
        for pid in $pids;do
            get_process_info_by_pid $pid
             
            awk -v p_name=$1 -v g_name=$2 -v p_status=$pro_status -v p_pid=$pid -v p_cpu=$pro_cpu -v p_mem=$pro_mem -v p_start_time="$pro_start_time" 'BEGIN{printf "%-20s%-20s%-20s%-20s%-20s%-20s%-20s\n",p_name,g_name,p_status,p_pid,p_cpu,p_mem,p_start_time}'
            # -v 定义的参数需要用双引号引起来"",否则会报错 awk: fatal: cannot open file `15' for reading (No such file or directory),主要是因为 p_start_time 中间有空格,需要""双引号引起来
            #awk -v p_name="$1" -v g_name="$2" -v p_status="$pro_status" -v p_pid="$pid" -v p_cpu="$pro_cpu" -v p_mem="$pro_mem" -v p_start_time="$pro_start_time" 'BEGIN{printf "%-20s%-20s%-20s%-20s%-20s%-20s%-20s\n",p_name,g_name,p_pid,p_status,p_cpu,p_mem,p_start_time}'
        done
    else
        awk -v p_name=$1 -v g_name=$2 'BEGIN{printf "%-20s%-20s%-20s%-20s%-20s%-20s%-20s\n",p_name,g_name,"NULL","Stopped","NULL","NULL","NULL"}'
    fi
}
 
# 打印头信息
awk 'BEGIN{printf "%-20s%-20s%-20s%-20s%-20s%-20s%-20s\n","ProcessName---","GroupName---","Status---","Pid---","CPU---","MEMORY---","StartTime---"}'
 
if [ $# -gt 0 ];then
    # 传递的是组
    if "$1" == "-g" ];then
        shift
        # 遍历传递参数的组
        for gn in $@;do
            # 组名是否在配置文件中, 执行不成功才会 continue 跳过
            is_group_in_config $gn || continue
            for pn in `get_all_process_by_group $gn`;do
                is_process_in_config $pn && format_print $pn $gn
            done
        done
    # 传递的是进程名
    else
        for pn in $@;do
            gn=`get_group_by_process_name $pn`
            is_process_in_config $pn && format_print $pn $gn
        done
    fi
else
    # 不添加参数,打印所有进程
    for pn in `get_all_process`;do
        gn=`get_group_by_process_name $pn`
        #echo "gn=$gn, pn=$pn"
                is_process_in_config $pn
        if [ $? -eq 0 ];then
            #echo "format print"
            format_print $pn $gn
        fi
    done
fi
 
#format_print nginx WEB
 
#group_name=`get_group_by_process_name $1`
#echo $group_name

  

 执行脚本 输出所有组内的进程信息

1
sh app_status1.sh

 

 执行脚本 输出指定组内的进程信息

1
sh app_status1.sh -g WEB

 

输出指定组内单个进程的信息 

1
sh app_status1.sh -g WEB DB

 

  

posted @   liujiacai  阅读(243)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示