请编写一个 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 文件。"
相关推荐
_OP_CHEN2 小时前
【Linux系统编程】(十七)揭秘 Linux 进程创建与终止:从 fork 到 exit 的底层逻辑全解析
linux·运维·服务器·操作系统·shell·进程·进程创建与终止
egoist202317 小时前
【Linux仓库】超越命令行用户:手写C语言Shell解释器,解密Bash背后的进程创建(附源码)
linux·c语言·bash·xshell·环境变量·命令行参数·内建命令
Lenyiin17 小时前
《 Linux 修炼全景指南: 八 》别再碎片化学习!掌控 Linux 开发工具链:gcc、g++、GDB、Bash、Python 与工程化实践
linux·python·bash·gdb·gcc·g++·lenyiin
m0_7431251317 小时前
claude --version 报错Claude Code on Windows requires git-bash (https://git-scm.com/downloads/win).
开发语言·git·bash
风雨飘逸17 小时前
【shell&bash进阶系列】(二十一)向脚本传递参数(shift和getopts)
linux·运维·服务器·经验分享·bash
24级计算机应用技术3班闫卓17 小时前
Bash Shell 基础操作全面指南
开发语言·bash
pr_note1 天前
via ladder
shell·tcl
编程小Y1 天前
Bash 替换机制
开发语言·chrome·bash
撩得Android一次心动1 天前
Android 四大组件——Service(服务)【基础篇2】
android·java·服务·四大组件·android 四大组件