自定义一个一键获取Linux系统状态信息的脚本
之前博客分享过一个Linux云服务器的一键测速脚本,可以很方便的来测试我们系统的IO网络等信息。对于系统状态信息的话我们一般使用top
命令也能够获取到,但这次分享一个自定义属于我们自己的获取Linux内存、磁盘IO、CPU使用率、负载等信息的脚本~
环境:CentOS 7 x64
先要准备好下面这个工具,不然的话磁盘IO部分的信息得不到哦
yum -y install sysstat
这次主要是分享获取信息的思路,也就是俗话说的"授人以渔",不同OS下关于各个方面的会有一点点出入,但是看完文章之后相信你也能针对自己的系统改出来的~~
一、简单呈现
脚本内容:
IP=`ifconfig | grep inet | grep -vE 'inet6|127.0.0.1' | awk '{print $2}'`
echo "IP地址:"$IP
cpu_num=`grep -c "model name" /proc/cpuinfo`
echo "cpu总核数:"$cpu_num
cpu_user=`top -b -n 1 | grep Cpu | awk '{print $2}' | cut -f 1 -d "%"`
echo "用户空间占用CPU百分比:"$cpu_user
cpu_system=`top -b -n 1 | grep Cpu | awk '{print $4}' | cut -f 1 -d "%"`
echo "内核空间占用CPU百分比:"$cpu_system
cpu_idle=`top -b -n 1 | grep Cpu | awk '{print $8}' | cut -f 1 -d "%"`
echo "空闲CPU百分比:"$cpu_idle
cpu_iowait=`top -b -n 1 | grep Cpu | awk '{print $10}' | cut -f 1 -d "%"`
echo "等待输入输出占CPU百分比:"$cpu_iowait
cpu_interrupt=`vmstat -n 1 1 | sed -n 3p | awk '{print $11}'`
echo "CPU中断次数:"$cpu_interrupt
cpu_context_switch=`vmstat -n 1 1 | sed -n 3p | awk '{print $12}'`
echo "CPU上下文切换次数:"$cpu_context_switch
cpu_load_15min=`uptime | awk '{print $12}' | cut -f 1 -d ','`
echo "CPU 15分钟前到现在的负载平均值:"$cpu_load_15min
cpu_load_5min=`uptime | awk '{print $11}' | cut -f 1 -d ','`
echo "CPU 5分钟前到现在的负载平均值:"$cpu_load_5min
cpu_load_1min=`uptime | awk '{print $10}' | cut -f 1 -d ','`
echo "CPU 1分钟前到现在的负载平均值:"$cpu_load_1min
cpu_task_length=`vmstat -n 1 1 | sed -n 3p | awk '{print $1}'`
echo "CPU任务队列长度:"$cpu_task_length
mem_total=`free | grep Mem | awk '{print $2}'`
echo "物理内存总量:"$mem_total
mem_sys_used=`free | grep Mem | awk '{print $3}'`
echo "已使用内存总量(操作系统):"$mem_sys_used
mem_sys_free=`free | grep Mem | awk '{print $4}'`
echo "剩余内存量(free部分):"$mem_sys_free
mem_sys_free2=`free | grep Mem | awk '{print $6}'`
echo "剩余内存量(buffer/cached部分):"$mem_sys_free2
mem_swap_total=`free | grep Swap | awk '{print $2}'`
echo "交换分区总大小:"$mem_swap_total
mem_swap_used=`free | grep Swap | awk '{print $3}'`
echo "已使用交换分区大小:"$mem_swap_used
mem_swap_free=`free | grep Swap | awk '{print $4}'`
echo "剩余交换分区大小:"$mem_swap_free
echo "指定设备(/dev/vda)的统计信息"
disk_sda_rs=`iostat -kx | grep vda| awk '{print $4}'`
echo "每秒向设备发起的读请求次数:"$disk_sda_rs
disk_sda_ws=`iostat -kx | grep vda| awk '{print $5}'`
echo "每秒向设备发起的写请求次数:"$disk_sda_ws
disk_sda_avgqu_sz=`iostat -kx | grep vda| awk '{print $9}'`
echo "向设备发起的I/O请求队列长度平均值"$disk_sda_avgqu_sz
disk_sda_await=`iostat -kx | grep vda| awk '{print $10}'`
echo "每次向设备发起的I/O请求平均时间:"$disk_sda_await
disk_sda_svctm=`iostat -kx | grep vda| awk '{print $11}'`
echo "向设备发起的I/O服务时间均值:"$disk_sda_svctm
disk_sda_util=`iostat -kx | grep vda| awk '{print $12}'`
echo "向设备发起I/O请求的CPU时间百分占比:"$disk_sda_util
在腾讯云轻量服务器2核4G内存的CentOS 7上运行结果:
(base) [root@VM-12-4-centos ~]# ./get_status.sh
IP地址:10.0.12.4 # 获取到的是腾讯云的内网IP
cpu总核数:2
用户空间占用CPU百分比:0.0
内核空间占用CPU百分比:3.1
空闲CPU百分比:96.8
等待输入输出占CPU百分比:0.0
CPU中断次数:7
CPU上下文切换次数:7
CPU 15分钟前到现在的负载平均值:0.10
CPU 5分钟前到现在的负载平均值:0.07
CPU 1分钟前到现在的负载平均值:0.05
CPU任务队列长度:3
物理内存总量:3880192
已使用内存总量(操作系统):662168
剩余内存量(空闲部分):258052
剩余内存量(活跃部分):2958916
交换分区总大小:0
已使用交换分区大小:0
剩余交换分区大小:0
指定设备(/dev/sda)的统计信息
每秒向设备发起的读请求次数:0.02
每秒向设备发起的写请求次数:2.54
向设备发起的I/O请求队列长度平均值0.00
每次向设备发起的I/O请求平均时间:2.31
向设备发起的I/O服务时间均值:1.33
向设备发起I/O请求的CPU时间百分占比:2.32
二、原理部分
这个脚本最核心的指令就是grep
等过滤器的应用,例如对于IP地址部分,我们通常使用ifconfig
指令来查看详细信息
(base) [root@VM-12-4-centos ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.12.4 netmask 255.255.252.0 broadcast 10.0.15.255
inet6 fe80::5054:ff:febe:5343 prefixlen 64 scopeid 0x20<link>
ether 52:54:00:be:53:43 txqueuelen 1000 (Ethernet)
RX packets 54575414 bytes 6480746019 (6.0 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 74744841 bytes 9002036667 (8.3 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 542694 bytes 44695694 (42.6 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 542694 bytes 44695694 (42.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
1.IP地址部分
我们的脚本可以写为
IP=`ifconfig | grep inet | grep -vE 'inet6|127.0.0.1' | awk '{print $2}'`
echo "IP地址:"$IP
其中:
ifconfig | grep inet
可以过滤出含有inet
的那一行grep -vE 'inet6|127.0.0.1'
则将上面那一步的结果进一步过滤,这次是清除带有inet6
和回环地址的两行awk
指令可以用于做字符串的空格分隔,例如awk '{print $2}'
则将上面过滤结果的行中,选择第二个内容进行输出,也就是我们想得到的IP地址了~- 最后就是使用shell脚本中最经典的
echo
命令,来打印出上面对变量(IP)进行赋值之后的结果~
2.CPU部分
核心数部分
通过cat /proc/cpuinfo
命令我们可以查看CPU的详细信息,之后可以从中提取到核心数信息
cpu_num=`grep -c "model name" /proc/cpuinfo`
echo "cpu总核数:"$cpu_num
其中grep -c
中的c可以理解为count,也就是统计有多少个model name,这样就可以得到核心数了
利用率部分
可以使用我们熟知的top
命令来获取信息,并且从中截取信息
cpu_user=`top -b -n 1 | grep Cpu | awk '{print $2}' | cut -f 1 -d "%"`
echo "用户空间占用CPU百分比:"$cpu_user
cpu_system=`top -b -n 1 | grep Cpu | awk '{print $4}' | cut -f 1 -d "%"`
echo "内核空间占用CPU百分比:"$cpu_system
cpu_idle=`top -b -n 1 | grep Cpu | awk '{print $8}' | cut -f 1 -d "%"`
echo "空闲CPU百分比:"$cpu_idle
cpu_iowait=`top -b -n 1 | grep Cpu | awk '{print $10}' | cut -f 1 -d "%"`
echo "等待输入输出占CPU百分比:"$cpu_iowait
其中top -b -n 1
中:
b代表处理top的输出成为适合打印到文件的样式,可以用这个创建日志等
n代表退出top前打印次数(类似于ping里面的-n)
因此这个指令代表使用top指令并只打印一次,结果如下
(base) [root@VM-12-4-centos ~]# top -b -n 1
top - 01:12:25 up 30 days, 3:43, 1 user, load average: 0.12, 0.08, 0.08
Tasks: 118 total, 1 running, 117 sleeping, 0 stopped, 0 zombie
%Cpu(s): 9.7 us, 3.2 sy, 0.0 ni, 87.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 3880192 total, 260992 free, 659368 used, 2959832 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 2924252 avail Mem
...省略
这时候又可以像上面一样提取信息了,不过这次出现了cut
指令
cut -f 1 -d "%" 解释:
-d "%" 是以%作为分隔符
-f 1显示以:分割每一行的第一段内容
因此对awk
后的第2段内容应用这个就是显示9.7了
剩下的内容也是一样的道理,想要什么信息我们就可以自己加上,其对应名字为:
#us 用户空间占用CPU百分比
#sy 内核空间占用CPU百分比
#ni 用户进程空间内改变过优先级的进程占用CPU百分比
#id 空闲CPU百分比
#wa 等待输入输出的CPU时间百分比
#hi 硬件中断
#si 软件中断
CPU负载部分
查看负载信息源自于uptime
指令
(base) [root@VM-12-4-centos ~]# uptime
12:33:23 up 30 days, 15:04, 1 user, load average: 0.25, 0.17, 0.14
其中可以显示的内容包括服务器运行时间、当前用户数量和3个负载值,之后我们按上面的思路继续进行分隔
对于负载值的含义(携程面试题):
核心数 | 平均负载 | 含义 |
---|---|---|
1 | 0.5 | 有50%的CPU是空闲状态 |
1 | 1 | CPU刚好被完全占用 |
1 | 2 | 至少有50%的进程抢不到CPU资源 |
2 | 2 | CPU刚好被完全占用 |
可见,2个CPU表明系统负荷可以达到2.0,此时每个CPU都达到100%的工作量。推广开来,n个CPU的电脑,可接受的系统负荷最大为n.0。
根据某运维大佬的博客,系统负荷的经验法则为:
1.0是系统负荷的理想值吗?
不一定,系统管理员往往会留一点余地,当这个值达到0.7,就应当引起注意了。经验法则是这样的:
当系统负荷持续大于0.7,你必须开始调查了,问题出在哪里,防止情况恶化。
当系统负荷持续大于1.0,你必须动手寻找解决办法,把这个值降下来。
当系统负荷达到5.0,就表明你的系统有很严重的问题,长时间没有响应,或者接近死机了。你不应该让系统达到这个值。
理解了负载之后,我们再来写成脚本获取负载的值吧
# 获取CPU15分钟前到现在的负载平均值
cpu_load_15min=`uptime | awk '{print $12}' | cut -f 1 -d ','`
echo "CPU 15分钟前到现在的负载平均值:"$cpu_load_15min
# 获取CPU5分钟前到现在的负载平均值
cpu_load_5min=`uptime | awk '{print $11}' | cut -f 1 -d ','`
echo "CPU 5分钟前到现在的负载平均值:"$cpu_load_5min
# 获取CPU1分钟前到现在的负载平均值
cpu_load_1min=`uptime | awk '{print $10}' | cut -f 1 -d ','`
echo "CPU 1分钟前到现在的负载平均值:"$cpu_load_1min
3.内存信息部分
在Linux系统中对于内存的状态信息主要通过free
命令来获取
(base) [root@VM-12-4-centos ~]# free
total used free shared buff/cache available
Mem: 3880192 659320 255812 928 2965060 2924300
Swap: 0 0 0
根据查阅到的资料,应用程序可用内存的定义为
available RAM for programs = free + buffers + cached
对于上面的信息,使用同样的思路进行过滤
mem_total=`free | grep Mem | awk '{print $2}'`
echo "物理内存总量:"$mem_total
mem_sys_used=`free | grep Mem | awk '{print $3}'`
echo "已使用内存总量(操作系统):"$mem_sys_used
mem_sys_free=`free | grep Mem | awk '{print $4}'`
echo "剩余内存量(free部分):"$mem_sys_free
mem_sys_free2=`free | grep Mem | awk '{print $6}'`
echo "剩余内存量(buffer/cached部分):"$mem_sys_free2
mem_swap_total=`free | grep Swap | awk '{print $2}'`
echo "交换分区总大小:"$mem_swap_total
mem_swap_used=`free | grep Swap | awk '{print $3}'`
echo "已使用交换分区大小:"$mem_swap_used
mem_swap_free=`free | grep Swap | awk '{print $4}'`
echo "剩余交换分区大小:"$mem_swap_free
4.磁盘IO信息部分
使用这个部分确保安装了sysstat
,没有的话使用下面的指令安装
yum -y install sysstat # for CentOS
apt-get -y install sysstat # for Ubuntu
(base) [root@VM-12-4-centos ~]# iostat
Linux 3.10.0-1127.19.1.el7.x86_64 (VM-12-4-centos) 04/23/2021 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
1.97 0.00 1.28 0.03 0.00 96.72
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
vda 2.56 0.25 25.29 662494 66963268
scd0 0.00 0.00 0.00 6222 0
提取信息为:
echo "指定设备(/dev/sda)的统计信息"
# 每秒向设备发起的读请求次数
disk_sda_rs=`iostat -kx | grep sda| awk '{print $4}'`
echo "每秒向设备发起的读请求次数:"$disk_sda_rs
# 每秒向设备发起的写请求次数
disk_sda_ws=`iostat -kx | grep sda| awk '{print $5}'`
echo "每秒向设备发起的写请求次数:"$disk_sda_ws
# 向设备发起的I/O请求队列长度平均值
disk_sda_avgqu_sz=`iostat -kx | grep sda| awk '{print $9}'`
echo "向设备发起的I/O请求队列长度平均值"$disk_sda_avgqu_sz
# 每次向设备发起的I/O请求平均时间
disk_sda_await=`iostat -kx | grep sda| awk '{print $10}'`
echo "每次向设备发起的I/O请求平均时间:"$disk_sda_await
# 向设备发起的I/O服务时间均值
disk_sda_svctm=`iostat -kx | grep sda| awk '{print $11}'`
echo "向设备发起的I/O服务时间均值:"$disk_sda_svctm
# 向设备发起I/O请求的CPU时间百分占比
disk_sda_util=`iostat -kx | grep sda| awk '{print $12}'`
echo "向设备发起I/O请求的CPU时间百分占比:"$disk_sda_util
这篇文章脚本部分参考于博客:波波说运维
完结撒花!