linux练手小项目:探测系统信息

看了b站上的一个教学视频,复习了一下拿取 linux 系统信息的方法,并跟着up写了一个小的脚本完成一系列需求。写一篇博文记录一下这个过程,以后回顾用。

课程地址:https://www.bilibili.com/video/BV1L7421T7mc

课程课件:https://gitee.com/coldbloodx/lsbs

需求

  • 显示当前运行的操作系统的名称版本
  • 显示当前系统的 CPU 信息:核心数量,生产厂商, CPU 型号
  • 显示当前系统的内存信息:内存总数,使用数量,空闲数量
  • 显示当前系统的磁盘信息,包括分区情况
  • 能兼容如下操作系统:
    • Ubuntu 22.04 -Y Pl
    • Rock Linux (Redhat/Centos) 8.x -5 Pl
    • Rock Linux (Redhat/Centos) 9.x Pl

过程要点

  1. 检测兼容性:
    • 方法一:找 /etc 目录下的 xxx-release 文件,里面放着系统名称版本信息。这一方法需要先去确定需要兼容的系统的文件所处位置。
    • 方法二: 利用用于展示开机欢迎信息的 /etc/issue 文件;如本机中该文件内容为 Ubuntu 20.04.6 LTS \n \l,解释见博文:/etc/issue,也可以在 man issue 文档中找到。
    • 方法三:使用 lsb_release 命令用来看当前 linux 系统的名称版本,但缺少该工具时需要使用方法一二兜底。
  2. 各个需求需要用到的获取信息方法已在上一篇文章记录:linux系统监控命令小记
  3. 注意学习正则表达式的使用,在处理信息时使用 ”sed + 正则“ 的组合很有用。 多翻阅 man 文档!中文的可以看前辈博文:shell脚本之sed详解
  4. 在写脚本时,为了方便维护,将每个需要实现的需求用函数分开。如使用 cpu_info()memory_info()disk_info() 等等。
  5. 在构思脚本运行的逻辑时,像平时编写程序那样思考:从 main() 出发;遇到类似 switch 的逻辑时将其单独划分开成为一个函数,如用于处理脚本参数的 parse_args()
  6. 处理 switch 逻辑时使用的 getopts 语法:Linux 命令行参数解析工具 getopts - 黄大仙的文章 - 知乎
  7. shell 脚本中处理错误返回时注意设置返回值为 非零值.
  8. 记得写上你脚本的 -h 选项处理!给出你脚本使用的方法!

遇到的坑

使用 echo 时,不带引号会自动将多余的空格去掉,从而导致 grep 的匹配出错

njucs@Ubuntu20:~/project/lsbs$ cat /proc/cpuinfo | grep "model name" | uniq
model name      : 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz
njucs@Ubuntu20:~/project/lsbs$ suki=$(cat /proc/cpuinfo | grep "model name" | uniq)
njucs@Ubuntu20:~/project/lsbs$ echo $suki
model name : 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz
njucs@Ubuntu20:~/project/lsbs$ echo "$suki"
model name      : 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz

源码展示

一共200行不到,主要是熟悉探测信息工具的使用。

#!/usr/bin/env bash

# ATTENTION: compatibility needed !!!
distro_name=''
kernel_version=''
function check_yum_based_distro() {
    echo "Waiting for you to perfect."
    exit 1

    # # echo "check yum/dnf based distro"    
    # # [root@rock8 lsbs]# cat /etc/rocky-release
    # # Rocky Linux release 8.9 (Green Obsidian)
    # if [ -f /etc/rocky-release ]; then
    #     distro="RockyLinux"
    #     version="$(sed -E 's#.*([0-9].[0-9]).*#\1#g' /etc/rocky-release)"
    #     return;
    # fi

    # # [root@rock8 lsbs]# cat /etc/centos-release
    # # Rocky Linux release 8.9 (Green Obsidian)
    # if [ -f /etc/centos-release ]; then
    #     distro="Centos"
    #     version="$(sed -E 's#.*([0-9].[0-9]).*#\1#g' /etc/redhat-release)"
    #     return
    # fi

    # if [ -f /etc/redhat-release ]; then
    #     distro="RHEL"
    #     version="$(sed -E 's#.*([0-9].[0-9]).*#\1#g' /etc/redhat-release)"
    #     return
    # fi
}
function check_apt_based_distro() {
    # njucs@Ubuntu20:~$ cat /etc/issue
    # Ubuntu 20.04.6 LTS \n \l
    if [[ -f /etc/issue ]]; then 
        # Ubuntu xx.yy.zz LTS
        sed -E 's/^(Ubuntu) ([0-9\.]*) ((LTS)?) (.*)$/\1 \2 \3/' /etc/issue | read distro_name 
        return
    fi
}

function distro_info() {
    # 检查lsb_release命令是否存在
    local is_exist_lsb_release=0
    which lsb_release > /dev/null 2>&1
    is_exist_lsb_release=$?
    
    if [[ $is_exist_lsb_release -eq 0 ]]; then
        distro_name=$(lsb_release -ds)
    else
        echo "WARNING: lsb_release command not found. "
        # 检查当前操作系统是否基于yum包管理器
        if which yum > /dev/null 2>&1; then
            check_yum_based_distroj
            return
        # 检查当前操作系统是否基于apt包管理器
        elif which apt > /dev/null 2>&1; then
            check_apt_based_distro  
            return
        else
            echo "ERROR: Unsupported operating system, exit... "
            exit 1
        fi
    fi

    if [[ -z "$distro_name" ]]; then
        echo "ERROR: Failed to get distro name, exit..."
        exit 1
    fi

}
function kernel_info() {
    # 获取内核信息
    kernel_version=$(uname -r)
}
function system_info() {

    # 获取系统信息
    distro_info
    kernel_info
    
    # 其他系统信息...

    echo "----------------SYSTEM INFO------------------------"
    echo "OS Distro:        ${distro_name}"
    echo "Kernel version:   ${kernel_version}"
}

function cpu_info() {
    # 获取CPU信息
    cpu_cores_numb=$(cat /proc/cpuinfo | grep "cpu cores" | uniq | cut -f 3 -d ' ')
    cpu_cores_vendor=$(cat /proc/cpuinfo | grep "vendor_id" | uniq | cut -d ' ' -f 2)
    cpu_cores_model=$(echo `cat /proc/cpuinfo | grep "model name" | uniq` | awk '{sub("model name : ","");print}')

    echo "------------------CPU INFO------------------------"
    echo "The CPU cores' number :       ${cpu_cores_numb}"
    echo "The CPU vendor        :       ${cpu_cores_vendor}"
    echo "The CPU model         :       ${cpu_cores_model}"
}

function memory_info() {
    # 获取内存信息
    mem_total=$(free -m | grep Mem | awk '{print $2}')
    mem_used=$(free -m | grep Mem | awk '{print $3}')
    mem_free=$(free -m | grep Mem | awk '{print $4}')

    echo "-------------------MEMORY-------------------------"
    echo "The total memory      :       ${mem_total} MB"
    echo "The used memory       :       ${mem_used} MB"
    echo "The free memory       :       ${mem_free} MB"
}

function disk_info() {
    echo "------------------DISK INFO------------------------"
    # 获取磁盘信息
    lsblk -o 'NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE' | grep -vE "sr0|loop*"
}


checkcpu=0
checkmem=0
checkdisk=0
summary=0

# system_detect.sh -s | [-c | -m | -d] | -h
function usage() {
    echo -e "System information summary tool.\n"
    echo -e "Usage:\n $(basename $0) [-h] [-s] [-c | -m | -d]\n"
    echo "Options:"
    echo "  -h       Show help"
    echo "  -s       Get summary"
    echo "  -c       Get CPU info"
    echo "  -m       Get memory info"
    echo "  -d       Get disk info"
}


function parse_args() {
    while getopts ":scmdh" opt; do
        case ${opt} in
            h)
                usage
                ;;
            s)
                summary=1
                ;;
            c)
                checkcpu=1
                ;;
            m)
                checkmem=1
                ;;
            d)
                checkdisk=1
                ;;
            \?)
                echo "Invalid option: -$OPTARG" 
                usage
                exit 1
                ;;
        esac
    done

    if [[ $OPTIND -eq 1 ]]; then
        echo "No options provided. Please provide -h for help."
        exit 1
    fi
}

function main() {
    parse_args "$@"
    
    system_info
    
    if [[ $summary -eq 1 ]]; then
        cpu_info
        memory_info
        disk_info
        exit 0
    else
        if [[ $checkcpu -eq 1 ]]; then
            cpu_info
        fi
        if [[ $checkmem -eq 1 ]]; then
            memory_info
        fi
        if [[ $checkdisk -eq 1 ]]; then
            disk_info
        fi
        exit 0
    fi
}

### !!! main starts here !!! ###
main "$@"
posted @ 2024-02-26 22:26  GrapefruitCat  阅读(47)  评论(0编辑  收藏  举报