Shell 脚本实现 Linux 系统监控

释放双眼,带上耳机,听听看~!

转载实验楼课程

一、实验介绍

1.1 实验内容

本课程实现 shell 脚本监控系统的各项参数,并可以将脚本加入系统环境中,可以直接在终端里执行。还添加了几个参数,一个脚本可以执行不同的操作。

1.2 知识点

本实验涵盖以下知识点:

  1. Bash 脚本编程
  2. 如何获取 Linux 系统信息
  3. 如何实时获取 Linux 资源使用率

1.3 实验环节

  • vim编辑器
  • shell解释器(linux自带)

1.4 适合人群

适合人群:本课程适合有shell语法基础,想学习shell脚本的实际使用的同学,可以加深对于shell脚本的认识

1.5 代码获取


1
2
3
4
5
6
7
8
9
1#获取
2http://labfile.oss.aliyuncs.com/courses/597/monitor.sh
3#运行
4bash monitor.sh
5#备注
6如果执行monitor -i安装提示输入密码。可以执行passwd root为root设置密码
7如果安装之后不能运行,修改/usr/bin/monitor.sh的权限
8
9

1.6 效果截图

在实验中,我们将逐步实现下面的功能需求:

  • 通过脚本查看系统的使用情况,实现对linux的系统监控。
  • 将写好的脚本加入系统环境,开启终端即可使用
  • 给脚本添加参数,可以实现不同的操作。

最终实现的脚本运行效果:

二、实验原理

2.1 主要命令介绍

  • 查看内存(free)
  • 查看磁盘(df)
  • 查看cpu占用率(top)
  • 查看内核版本(uname)

这些命令是linux管理员必须耳熟能详的基本命令,本课程的监控脚本,也是根据这些命令的返回值做处理,然后打印在终端的,同学们可以敲一敲这些命令,看看他们的基本用法。

命令详解请查看
http://man.linuxde.net/

2.2 shell编程注意

  • 1
    1` ```` `

     用法 这个符号可以保存命令的返回值,如


1
2
3
4
5
1 PATH=`pwd` #也可以写成 PAHT=$(pwd)
2 echo $PATH
3 #输出pwd命令的值,也就是当前路径
4
5
  • 参数说明

$1表示第一个参数,$2 表示第二个参数,$#表示参数个数

如果读者对于这些不熟悉,要先学习高级Bash脚本编程指南,其中shell的基本语法

三、实验步骤

打开终端,进入Code目录,创建文件tecmint_monitor.sh。

getopts:可以获取用户在命令下的参数,然后根据不同的参数进行不同的操作。它的使用方法是getopts option_string variable,option_string 是指字符串,会逐个匹配,variable 每次匹配成功的选项。


1
2
3
4
5
6
7
8
9
10
11
12
1#! /bin/bash
2while getopts ivh name # getopts 有三个参数,分别执行安装,查看版本,帮助说明
3do
4        case $name in
5          i)iopt=1;;
6          v)vopt=1;;
7          h)hopt=1;;
8         *)echo "Invalid arg";;
9        esac
10done
11
12

这个脚本主要有 -ivh 三个参数,分别执行安装脚本,查看版本,帮助说明,你也可以添加自己想要的参数。如果不加参数,默认执行系统的监控命令并打印到屏幕上。

3.1 有关参数 i 的模块

这个部分主要是将脚本添加到环境的目录里,通过终端就可以执行命令。


1
2
3
4
5
6
7
8
9
10
11
12
13
1if [[ ! -z $iopt ]] #如果iopt非空则执行
2then
3{
4wd=$(pwd)
5basename "$(test -L "$0" && readlink "$0" || echo "$0")" > /tmp/scriptname
6#basename命令会删掉所有的前缀包括最后一个slash(‘/’)字符,然后将字符串显示出来
7scriptname=$(echo -e -n $wd/ && cat /tmp/scriptname)
8#scriptname就是tecmint_monitor.sh的地址
9su -c "cp $scriptname /usr/bin/monitor" root && echo "Congratulations! Script Installed, now run monitor Command" || echo "Installation failed"
10}
11fi
12
13

3.2 有关参数 v 的模块

这个部分是查看脚本的版本,版权等信息。


1
2
3
4
5
6
7
8
1if [[ ! -z $vopt ]]
2then
3{
4echo -e "tecmint_monitor version 0.1\nReleased Under Apache 2.0 License"
5}
6fi
7
8

3.3 有关参数 h 的模块

这个部分是添加帮助信息,方便其他人使用


1
2
3
4
5
6
7
8
9
10
1if [[ ! -z $hopt ]]
2then
3{
4echo -e " -i                                Install script"
5echo -e " -v                                Print version information and exit"
6echo -e " -h                                Print help (this information) and exit"
7}
8fi
9
10

3.4提取信息设置变量

先设置一些好记的变量名,这样方便阅读,比直接看代码要更容易一点。


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
1clear
2
3unset tecreset os architecture kernelrelease internalip externalip nameserver loadaverage
4# unset命令用于删除已定义的shell变量(包括环境变量)和shell函数。
5# 关于unset更多的信息可以查看http://www.runoob.com/linux/linux-comm-unset.html
6# 定义变量 tecreset
7tecreset=$(tput sgr0)
8
9# 查看是否可以连网
10ping -c 1 www.baidu.com &> /dev/null && echo -e '\E[32m'"Internet: $tecreset Connected" || echo -e '\E[32m'"Internet: $tecreset Disconnected"
11# '\E[32m' 将打印的信息设置为绿色
12# 查看系统的类型
13os=$(uname -o)
14echo -e '\E[32m'"Operating System Type :" $tecreset $os
15
16# 查看系统的版本和名称
17###################################
18OS=`uname -s`
19REV=`uname -r`
20MACH=`uname -m`
21
22GetVersionFromFile()
23{
24    VERSION=`cat $1 | tr "\n" ' ' | sed s/.*VERSION.*=\ // `
25}
26
27

查看操作系统的类型,不同的操作系统指令是不一样的。看到大段的代码不要紧张,其实逻辑很简单。


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
1
2if [ "${OS}" = "SunOS" ] ; then
3    OS=Solaris
4    ARCH=`uname -p`
5    OSSTR="${OS} ${REV}(${ARCH} `uname -v`)"
6# uname命令用于打印当前系统相关信息(内核版本号、硬件架构、主机名称和操作系统类型等)。
7elif [ "${OS}" = "AIX" ] ; then
8    OSSTR="${OS} `oslevel` (`oslevel -r`)"
9#AIX是IBM开发的一套类UNIX操作系统,关于它更多的指令可以查看http://www.cnblogs.com/sbaicl/articles/2947795.html
10elif [ "${OS}" = "Linux" ] ; then
11    KERNEL=`uname -r`
12    if [ -f /etc/redhat-release ] ; then
13        DIST='RedHat'
14        PSUEDONAME=`cat /etc/redhat-release | sed s/.*\(// | sed s/\)//`
15        REV=`cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//`
16#sed通常用来匹配一个或多个正则表达式的文本进行处理,可以查看http://coolshell.cn/articles/9104.html
17    elif [ -f /etc/SuSE-release ] ; then
18        DIST=`cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//`
19        REV=`cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //`
20    elif [ -f /etc/mandrake-release ] ; then
21        DIST='Mandrake'
22        PSUEDONAME=`cat /etc/mandrake-release | sed s/.*\(// | sed s/\)//`
23        REV=`cat /etc/mandrake-release | sed s/.*release\ // | sed s/\ .*//`
24    elif [ -f /etc/debian_version ] ; then
25        DIST="Debian `cat /etc/debian_version`"
26        REV=""
27
28    fi
29    if ${OSSTR} [ -f /etc/UnitedLinux-release ] ; then
30        DIST="${DIST}[`cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//`]"
31    fi
32
33    OSSTR="${OS} ${DIST} ${REV}(${PSUEDONAME} ${KERNEL} ${MACH})"
34
35fi
36
37

最后就是监控系统的各种信息,并打印到屏幕


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
1查看操作系统版本
2echo -e '\E[32m'"OS Version :" $tecreset $OSSTR
3# 查看系统的类型
4architecture=$(uname -m)
5echo -e '\E[32m'"Architecture :" $tecreset $architecture
6
7# 查看内核的版本
8kernelrelease=$(uname -r)
9echo -e '\E[32m'"Kernel Release :" $tecreset $kernelrelease
10
11# 查看主机名
12echo -e '\E[32m'"Hostname :" $tecreset $HOSTNAME
13
14# 查看内网地址
15internalip=$(hostname -I)
16echo -e '\E[32m'"Internal IP :" $tecreset $internalip
17
18# 查看外网地址
19externalip=$(curl -s ipecho.net/plain;echo)
20echo -e '\E[32m'"External IP : $tecreset "$externalip
21
22# 查看DNS
23nameservers=$(cat /etc/resolv.conf | sed '1 d' | awk '{print $2}')
24echo -e '\E[32m'"Name Servers :" $tecreset $nameservers
25
26# 查看登陆的用户
27who>/tmp/who
28echo -e '\E[32m'"Logged In users :" $tecreset && cat /tmp/who
29
30# 查看系统内存使用情况
31free -h | grep -v + > /tmp/ramcache
32echo -e '\E[32m'"Ram Usages :" $tecreset
33cat /tmp/ramcache | grep -v "Swap"
34echo -e '\E[32m'"Swap Usages :" $tecreset
35cat /tmp/ramcache | grep -v "Mem"
36
37# 查看磁盘使用情况
38df -h| grep 'Filesystem\|/dev/sda*' > /tmp/diskusage
39echo -e '\E[32m'"Disk Usages :" $tecreset
40cat /tmp/diskusage
41
42# 查看系统的负载情况
43loadaverage=$(top -n 1 -b | grep "load average:" | awk '{print $10 $11 $12}')
44echo -e '\E[32m'"Load Average :" $tecreset $loadaverage
45
46# 查看系统的运行时间
47tecuptime=$(uptime | awk '{print $3,$4}' | cut -f1 -d,)
48echo -e '\E[32m'"System Uptime Days/(HH:MM) :" $tecreset $tecuptime
49
50# 删除上面使用的变量,释放资源
51unset tecreset os architecture kernelrelease internalip externalip nameserver loadaverage
52
53# 删除临时文件
54rm /tmp/who /tmp/ramcache /tmp/diskusage
55}
56fi
57
58

四、实验总结

通过这个小项目,加强了对shell编程的理解,不仅可以执行脚本,还可以将脚本安装到系统环境中,直接执行命令。从实践中学习,把代码敲一遍,就能体会编程的乐趣了:-)

最后附上源代码


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
1#! /bin/bash
2# unset any variable which system may be using
3# clear the screen
4
5
6while getopts ivh name
7do
8        case $name in
9          i)iopt=1;;
10          v)vopt=1;;
11          h)hopt=1;;
12         *)echo "Invalid arg";;
13        esac
14done
15#
16if [[ ! -z $iopt ]]
17then
18{
19wd=$(pwd)
20basename "$(test -L "$0" && readlink "$0" || echo "$0")" > /tmp/scriptname
21scriptname=$(echo -e -n $wd/ && cat /tmp/scriptname)
22su -c "cp $scriptname /usr/bin/monitor" root && echo "Congratulations! Script Installed, now run monitor Command" || echo "Installation failed"
23}
24fi
25
26if [[ ! -z $vopt ]]
27then
28{
29echo -e "tecmint_monitor version 0.1\nDesigned by Tecmint.com\nReleased Under Apache 2.0 License"
30}
31fi
32if [[ ! -z $hopt ]]
33then
34{
35echo -e " -i                                Install script"
36echo -e " -v                                Print version information and exit"
37echo -e " -h                                Print help (this information) and exit"
38}
39fi
40
41if [[ $# -eq 0 ]]
42then
43{
44clear
45
46unset tecreset os architecture kernelrelease internalip externalip nameserver loadaverage
47
48# Define Variable tecreset
49tecreset=$(tput sgr0)
50
51# Check if connected to Internet or not
52ping -c 1 www.baidu.com &> /dev/null && echo -e '\E[32m'"Internet: $tecreset Connected" || echo -e '\E[32m'"Internet: $tecreset Disconnected"
53
54# Check OS Type
55os=$(uname -o)
56echo -e '\E[32m'"Operating System Type :" $tecreset $os
57
58# Check OS Release Version and Name
59###################################
60OS=`uname -s`
61REV=`uname -r`
62MACH=`uname -m`
63
64GetVersionFromFile()
65{
66    VERSION=`cat $1 | tr "\n" ' ' | sed s/.*VERSION.*=\ // `
67}
68
69if [ "${OS}" = "SunOS" ] ; then
70    OS=Solaris
71    ARCH=`uname -p`
72    OSSTR="${OS} ${REV}(${ARCH} `uname -v`)"
73elif [ "${OS}" = "AIX" ] ; then
74    OSSTR="${OS} `oslevel` (`oslevel -r`)"
75elif [ "${OS}" = "Linux" ] ; then
76    KERNEL=`uname -r`
77    if [ -f /etc/redhat-release ] ; then
78        DIST='RedHat'
79        PSUEDONAME=`cat /etc/redhat-release | sed s/.*\(// | sed s/\)//`
80        REV=`cat /etc/redhat-release | sed s/.*release\ // | sed s/\ .*//`
81    elif [ -f /etc/SuSE-release ] ; then
82        DIST=`cat /etc/SuSE-release | tr "\n" ' '| sed s/VERSION.*//`
83        REV=`cat /etc/SuSE-release | tr "\n" ' ' | sed s/.*=\ //`
84    elif [ -f /etc/mandrake-release ] ; then
85        DIST='Mandrake'
86        PSUEDONAME=`cat /etc/mandrake-release | sed s/.*\(// | sed s/\)//`
87        REV=`cat /etc/mandrake-release | sed s/.*release\ // | sed s/\ .*//`
88    elif [ -f /etc/debian_version ] ; then
89        DIST="Debian `cat /etc/debian_version`"
90        REV=""
91
92    fi
93    if ${OSSTR} [ -f /etc/UnitedLinux-release ] ; then
94        DIST="${DIST}[`cat /etc/UnitedLinux-release | tr "\n" ' ' | sed s/VERSION.*//`]"
95    fi
96
97    OSSTR="${OS} ${DIST} ${REV}(${PSUEDONAME} ${KERNEL} ${MACH})"
98
99fi
100
101##################################
102#cat /etc/os-release | grep 'NAME\|VERSION' | grep -v 'VERSION_ID' | grep -v 'PRETTY_NAME' > /tmp/osrelease
103#echo -n -e '\E[32m'"OS Name :" $tecreset  && cat /tmp/osrelease | grep -v "VERSION" | grep -v CPE_NAME | cut -f2 -d\"
104#echo -n -e '\E[32m'"OS Version :" $tecreset && cat /tmp/osrelease | grep -v "NAME" | grep -v CT_VERSION | cut -f2 -d\"
105echo -e '\E[32m'"OS Version :" $tecreset $OSSTR
106
107architecture=$(uname -m)
108echo -e '\E[32m'"Architecture :" $tecreset $architecture
109
110
111kernelrelease=$(uname -r)
112echo -e '\E[32m'"Kernel Release :" $tecreset $kernelrelease
113
114
115echo -e '\E[32m'"Hostname :" $tecreset $HOSTNAME
116
117
118internalip=$(hostname -I)
119echo -e '\E[32m'"Internal IP :" $tecreset $internalip
120
121
122externalip=$(curl -s ipecho.net/plain;echo)
123echo -e '\E[32m'"External IP : $tecreset "$externalip
124
125
126nameservers=$(cat /etc/resolv.conf | sed '1 d' | awk '{print $2}')
127echo -e '\E[32m'"Name Servers :" $tecreset $nameservers
128
129
130who>/tmp/who
131echo -e '\E[32m'"Logged In users :" $tecreset && cat /tmp/who
132
133
134free -h | grep -v + > /tmp/ramcache
135echo -e '\E[32m'"Ram Usages :" $tecreset
136cat /tmp/ramcache | grep -v "Swap"
137echo -e '\E[32m'"Swap Usages :" $tecreset
138cat /tmp/ramcache | grep -v "Mem"
139
140
141df -h| grep 'Filesystem\|/dev/sda*' > /tmp/diskusage
142echo -e '\E[32m'"Disk Usages :" $tecreset
143cat /tmp/diskusage
144
145
146loadaverage=$(top -n 1 -b | grep "load average:" | awk '{print $10 $11 $12}')
147echo -e '\E[32m'"Load Average :" $tecreset $loadaverage
148
149
150tecuptime=$(uptime | awk '{print $3,$4}' | cut -f1 -d,)
151echo -e '\E[32m'"System Uptime Days/(HH:MM) :" $tecreset $tecuptime
152
153
154unset tecreset os architecture kernelrelease internalip externalip nameserver loadaverage
155
156rm /tmp/who /tmp/ramcache /tmp/diskusage
157}
158fi
159shift $(($OPTIND -1))
160# shift命令用于对参数的移动(左移)。可以查看http://blog.csdn.net/zhu_xun/article/details/24796235
161#
162

给TA打赏
共{{data.count}}人
人已打赏
安全技术安全运维

Windows服务器如何发现被黑

2018-5-20 12:24:31

安全技术

用node.js做cluster,监听异常的邮件提醒服务

2021-12-21 16:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索