请编写一个 Bash 脚本检查系统中的所有服务状态(中等)

👨‍⚕️ 主页: gis分享者

👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍⚕️ 收录于专栏:Shell 面试

文章目录

  • 一、🍀前言
    • [1.1 ☘️示例](#1.1 ☘️示例)
    • [1.2 ☘️知识扩展](#1.2 ☘️知识扩展)

一、🍀前言

可以使用 systemctl 命令来列出和检查服务状态,这是一个用于管理 Systemd 服务的命令行工具。

1.1 ☘️示例

基本示例:

powershell 复制代码
#!/bin/bash

# 列出所有服务并保存到变量
services=$(systemctl list-units --type=service --all)

# 打印标题
echo "Service Name            Load State   Active State   Sub State"

# 读取每个服务的状态
while read -r service; do
    # 检查服务名称和状态
    echo "$service" | awk '{printf "%-20s %-12s %-12s %-12s\n", $1, $2, $3, $4}'
done <<< "$services"

运行这个脚本,它会列出所有的服务名称和它们的加载状态、激活状态及子状态。

示例一:

powershell 复制代码
#!/bin/bash

# 系统服务状态检查脚本
# 用于检查系统中所有服务的运行状态

echo "=================================="
echo "    系统服务状态检查报告"
echo "=================================="
echo

# 检查系统类型和可用的命令
check_system_type() {
    if command -v systemctl >/dev/null 2>&1; then
        echo "检测到 systemd 系统"
        return 1
    elif command -v service >/dev/null 2>&1; then
        echo "检测到 SysVinit 系统"
        return 2
    else
        echo "未检测到支持的服务管理工具"
        return 0
    fi
}

# 使用systemctl检查服务状态 (systemd系统)
check_systemd_services() {
    echo "正在检查 systemd 服务状态..."
    echo "----------------------------------"
    
    # 统计信息
    local total_services=$(systemctl list-units --type=service | grep -v "LOAD\|listed" | wc -l)
    local active_services=$(systemctl list-units --type=service --state=active | grep -v "LOAD\|listed" | wc -l)
    local inactive_services=$(systemctl list-units --type=service --state=inactive | grep -v "LOAD\|listed" | wc -l)
    local failed_services=$(systemctl list-units --type=service --state=failed | grep -v "LOAD\|listed" | wc -l)
    
    echo "总服务数: $total_services"
    echo "运行中: $active_services"
    echo "已停止: $inactive_services"
    echo "失败: $failed_services"
    echo
    
    # 显示失败的服务
    if [ $failed_services -gt 0 ]; then
        echo "失败的服务列表:"
        systemctl list-units --type=service --state=failed --no-pager | grep -v "LOAD\|listed"
        echo
    fi
    
    # 显示所有服务状态摘要
    echo "服务状态摘要:"
    systemctl list-units --type=service --no-pager | grep -v "LOAD\|listed" | awk '{print $2": "$4}' | sort
}

# 使用service命令检查服务状态 (SysVinit系统)
check_sysvinit_services() {
    echo "正在检查 SysVinit 服务状态..."
    echo "----------------------------------"
    
    # 检查 /etc/init.d/ 目录下的服务
    if [ -d "/etc/init.d/" ]; then
        local service_count=0
        local running_count=0
        local stopped_count=0
        
        for service in /etc/init.d/*; do
            if [ -f "$service" ] && [ -x "$service" ]; then
                service_name=$(basename "$service")
                service_count=$((service_count + 1))
                
                # 检查服务状态
                if $service status >/dev/null 2>&1; then
                    echo "$service_name: 运行中"
                    running_count=$((running_count + 1))
                else
                    echo "$service_name: 已停止"
                    stopped_count=$((stopped_count + 1))
                fi
            fi
        done
        
        echo
        echo "统计信息:"
        echo "总服务数: $service_count"
        echo "运行中: $running_count"
        echo "已停止: $stopped_count"
    else
        echo "未找到服务目录 /etc/init.d/"
    fi
}

# 检查特定服务
check_specific_service() {
    local service_name=$1
    if systemctl is-active --quiet "$service_name" 2>/dev/null; then
        echo "$service_name: 运行中"
    elif systemctl is-active --quiet "$service_name" 2>/dev/null; then
        echo "$service_name: 已停止"
    else
        echo "$service_name: 服务不存在或无法访问"
    fi
}

# 主程序
main() {
    # 获取系统类型
    check_system_type
    system_type=$?
    
    case $system_type in
        1)
            check_systemd_services
            ;;
        2)
            check_sysvinit_services
            ;;
        *)
            echo "错误: 不支持的系统类型"
            exit 1
            ;;
    esac
    
    echo
    echo "=================================="
    echo "          检查完成"
    echo "=================================="
}

# 检查是否提供了特定服务名称作为参数
if [ $# -eq 1 ]; then
    echo "检查特定服务: $1"
    check_specific_service "$1"
else
    # 执行完整检查
    main
fi

示例二:

powershell 复制代码
#!/bin/bash
 
# 服务状态检查函数
check_service_status() {
    # 检测初始化系统类型
    if [[ $(ps --no-headers -o comm 1) == "systemd" ]]; then
        echo -e "\n[Systemd 系统服务状态检查]"
        # 获取所有systemd服务单元
        systemctl list-units --type=service --all --no-pager | awk 'NR>1 && !/loaded/ {print $1}' | while read -r service; do
            # 过滤掉无效条目
            if [[ "$service" =~ \.service$ ]]; then
                active_status=$(systemctl is-active "$service")
                enabled_status=$(systemctl is-enabled "$service" 2>/dev/null || echo "unknown")
                printf "%-45s %-15s %-15s\n" "${service%.*}" "[Active: $active_status]" "[Enabled: $enabled_status]"
            fi
        done
    else
        echo -e "\n[SysV Init 系统服务状态检查]"
        # 检查传统init系统服务
        if [ -d /etc/init.d ]; then
            find /etc/init.d/ -executable -type f -printf "%f\n" | while read -r service; do
                status_output=$(service "$service" status 2>&1)
                if [[ "$status_output" =~ "is running" ]]; then
                    state="running"
                else
                    state="stopped"
                fi
                printf "%-45s %-15s\n" "$service" "[Status: $state]"
            done
        else
            echo "未找到SysV初始化系统服务目录"
        fi
    fi
}
 
# 执行主函数
check_service_status | less -S

脚本特点说明:

  • 智能初始化系统检测:

通过检查PID 1进程判断实际使用的初始化系统

支持systemd和传统SysV init系统

  • systemd系统处理:

使用systemctl list-units获取完整服务列表

显示服务激活状态(active/inactive)和启用状态(enabled/disabled)

过滤无效条目和标题行

  • SysV系统处理:

检查/etc/init.d目录中的可执行服务脚本

解析基础运行状态(running/stopped)

  • 输出优化:

格式化列对齐输出

通过管道连接less命令实现分页浏览

支持宽字符显示(-S参数保持折行)

1.2 ☘️知识扩展

1)systemctl 命令:systemctl 是一个核心工具,用于控制 Systemd 系统及服务管理器。你可以用它来启动、停止、重启、禁用和启用服务,还可以用来检查服务状态。

2)awk:这是一个非常强大的文本处理工具,特别适合格式化和筛选文本内容。在这个脚本中,我使用 awk 来格式化输出。

3)重定向操作符 < 和 <<: Bash 中有多种重定向技术。这里使用了 <<<,它将右侧的字符串作为输入提供给左侧命令。这是一种方便的方式来处理多行字符串。

4)脚本的改进:为了使脚本更易读和更具扩展性,我们可以考虑以下几点:

添加错误处理:检查 systemctl 命令是否成功执行。

提供选择特定服务进行检查的功能。

输出结果到文件,以方便后续查阅。

改进版本的脚本:

powershell 复制代码
#!/bin/bash

# 检查 systemctl 命令是否可用
if ! command -v systemctl &> /dev/null
then
    echo "systemctl 命令不可用,请确保 Systemd 已安装。"
    exit 1
fi

# 获取所有服务的状态
services=$(systemctl list-units --type=service --all)

# 打印标题
printf "%-20s %-12s %-12s %-12s\n" "Service Name" "Load State" "Active State" "Sub State"

# 读取每个服务的状态并格式化输出
while read -r service; do
    echo "$service" | awk '{printf "%-20s %-12s %-12s %-12s\n", $1, $2, $3, $4}'
done <<< "$services"

# 将结果保存到文件
echo "$services" > service_status.txt

echo "服务状态检查完毕,结果已保存到 service_status.txt 文件。"
相关推荐
IMPYLH4 小时前
Linux 的 unexpand 命令
linux·运维·服务器·bash
IMPYLH11 小时前
Linux 的 uniq 命令
linux·运维·服务器·bash
IMPYLH17 小时前
Linux 的 unlink 命令
linux·运维·服务器·bash
Irene19912 天前
Shell 相关基础入门,在 Ubuntu 与 CentOS Shell 中的语法差异总结(bash、dash、sh)
shell
小肝一下2 天前
5. 基础IO
android·linux·shell·基础io·操作系统底层·伊涅夫·伊雷娜
YuanDaima20483 天前
Docker 工程化安装与核心命令实战
运维·人工智能·docker·微服务·容器·bash
红茶要加冰3 天前
七、正则表达式
linux·运维·正则表达式·shell
lifewange4 天前
WSL安装问题解决
shell
AdCj34 天前
放弃第三方框架,用系统自带工具玩转 Shell 测试
shell·测试
红茶要加冰4 天前
九、文本处理三剑客——sed
linux·运维·服务器·正则表达式·shell