Linux systemctl命令详解

systemctl 是 systemd 系统和服务管理器的主要命令行工具,用于控制系统服务、管理启动过程、查看系统状态等。它是现代Linux发行版中替代传统 init 系统的核心工具。

一、命令简介

systemctl 是 systemd 生态系统中的核心命令,提供了对系统服务的全面控制,包括启动、停止、重启、启用、禁用服务,以及查看服务状态和日志。它还提供了系统状态查看、电源管理等功能。

特点: 并行启动服务、依赖管理、按需启动、服务快照、系统状态监控、日志集成。

二、安装systemctl

systemctl 是 systemd 的一部分,在现代 Linux 发行版中默认已安装:

检查是否安装

which systemctl

如果未安装,说明你的系统可能没有使用 systemd(如使用 SysVinit 或 Upstart)。在大多数现代 Linux 发行版中,systemd 是默认的初始化系统。

验证安装和版本

systemctl --version

三、基本语法

systemctl [选项] [命令] [单元名...]

四、常用选项

选项 说明
-h--help 显示帮助信息
--version 显示版本信息
--system 连接到系统管理器(默认)
--user 连接到用户服务管理器
-t--type= 指定单元类型(service, socket, mount等)
-a--all 显示所有单元,包括不活动的
-l--full 不截断输出,显示完整内容
--no-pager 不将输出通过分页器显示
--no-legend 不显示列标题和脚注
-q--quiet 减少输出信息
-f--failed 仅显示失败的单元
--state= 按状态过滤单元
-p--property= 显示指定属性
--value 仅显示属性值,不显示属性名
--plain 以纯文本格式输出列表

五、单元(Unit)类型

systemd 使用单元(Unit)来管理系统资源,常见的单元类型包括:

单元类型 扩展名 说明 示例
服务单元 .service 系统服务,管理守护进程 nginx.service, sshd.service
挂载单元 .mount 文件系统挂载点 home.mount, mnt-data.mount
套接字单元 .socket 进程间通信套接字 ssh.socket, dbus.socket
设备单元 .device 内核识别的设备文件 dev-sda.device
定时器单元 .timer 定时器,用于调度任务 daily-backup.timer
路径单元 .path 文件或目录路径监控 spool.path
交换单元 .swap 交换分区或文件 swapfile.swap
目标单元 .target 单元组,类似于运行级别 multi-user.target
切片单元 .slice 资源管理切片 user.slice
作用域单元 .scope 外部创建的进程组 session-1.scope

六、常用命令

1. 系统状态查看

命令 说明 示例
systemctl status 查看系统整体状态 systemctl status
systemctl status [单元] 查看指定单元状态 systemctl status nginx
systemctl is-active [单元] 检查单元是否活动 systemctl is-active sshd
systemctl is-enabled [单元] 检查单元是否启用 systemctl is-enabled httpd
systemctl is-failed [单元] 检查单元是否失败 systemctl is-failed mysql
systemctl list-units 列出所有活动单元 systemctl list-units
systemctl list-units --all 列出所有单元(包括不活动的) systemctl list-units --all
systemctl list-units --type=service 列出所有服务单元 systemctl list-units -t service
systemctl list-unit-files 列出所有单元文件 systemctl list-unit-files
systemctl list-dependencies [单元] 列出单元的依赖关系 systemctl list-dependencies nginx

2. 服务控制

命令 说明 示例
systemctl start [单元] 启动单元 systemctl start nginx
systemctl stop [单元] 停止单元 systemctl stop nginx
systemctl restart [单元] 重启单元 systemctl restart nginx
systemctl reload [单元] 重新加载配置(不重启) systemctl reload nginx
systemctl try-restart [单元] 仅在运行状态下重启 systemctl try-restart nginx
systemctl reload-or-restart [单元] 重载配置,失败则重启 systemctl reload-or-restart nginx
systemctl kill [单元] 向单元发送信号 systemctl kill nginx
systemctl daemon-reload 重新加载systemd配置 systemctl daemon-reload

3. 服务启用/禁用

命令 说明 示例
systemctl enable [单元] 启用单元开机自启 systemctl enable nginx
systemctl disable [单元] 禁用单元开机自启 systemctl disable nginx
systemctl reenable [单元] 重新启用单元 systemctl reenable nginx
systemctl preset [单元] 重置为预设状态 systemctl preset nginx
systemctl mask [单元] 屏蔽单元(防止启动) systemctl mask nginx
systemctl unmask [单元] 取消屏蔽单元 systemctl unmask nginx

4. 系统管理

命令 说明 示例
systemctl reboot 重启系统 systemctl reboot
systemctl poweroff 关机 systemctl poweroff
systemctl halt 停止系统 systemctl halt
systemctl suspend 挂起系统 systemctl suspend
systemctl hibernate 休眠系统 systemctl hibernate
systemctl hybrid-sleep 混合休眠(挂起+休眠) systemctl hybrid-sleep
systemctl rescue 进入救援模式 systemctl rescue
systemctl emergency 进入紧急模式 systemctl emergency
systemctl default 进入默认模式 systemctl default

七、使用示例

示例1:查看系统状态

# 查看系统整体状态
systemctl status

# 查看特定服务状态
systemctl status nginx.service

# 查看简洁状态
systemctl status nginx --no-pager

输出示例:

● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2024-01-01 10:00:00 UTC; 1h ago
     Docs: man:nginx(8)
 Main PID: 1234 (nginx)
    Tasks: 2 (limit: 4915)
   Memory: 10.0M
   CGroup: /system.slice/nginx.service
           ├─1234 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
           └─1235 nginx: worker process

示例2:管理Web服务

# 启动Nginx服务
sudo systemctl start nginx

# 停止Nginx服务
sudo systemctl stop nginx

# 重启Nginx服务
sudo systemctl restart nginx

# 重新加载Nginx配置
sudo systemctl reload nginx

# 设置Nginx开机自启
sudo systemctl enable nginx

# 禁用Nginx开机自启
sudo systemctl disable nginx

# 查看Nginx是否启用
systemctl is-enabled nginx

示例3:查看所有服务

# 列出所有运行中的服务
systemctl list-units --type=service

# 列出所有服务(包括未运行的)
systemctl list-units --type=service --all

# 列出所有失败的服务
systemctl list-units --type=service --failed

# 以树状图显示服务依赖关系
systemctl list-dependencies nginx.service

示例4:创建自定义服务

创建自定义服务文件 /etc/systemd/system/myapp.service

[Unit]
Description=My Custom Application
After=network.target

[Service]
Type=simple
User=myappuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/myapp
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

启用并启动服务:

# 重新加载systemd配置
sudo systemctl daemon-reload

# 启用服务
sudo systemctl enable myapp.service

# 启动服务
sudo systemctl start myapp.service

# 查看服务状态
systemctl status myapp.service

示例5:使用定时器

# 列出所有定时器
systemctl list-timers

# 查看特定定时器的详细信息
systemctl status daily-backup.timer

# 手动运行定时器对应的服务
sudo systemctl start daily-backup.service

# 启用定时器
sudo systemctl enable daily-backup.timer

# 立即启动定时器
sudo systemctl start daily-backup.timer

示例6:用户服务管理

# 管理用户级服务(无需sudo)
systemctl --user status

# 启动用户服务
systemctl --user start myuserapp

# 启用用户服务开机自启
systemctl --user enable myuserapp

# 查看用户服务
systemctl --user list-units --type=service

# 设置用户服务管理器开机启动(允许用户服务在登录前运行)
sudo loginctl enable-linger $USER

示例7:日志查看

# 查看服务日志(使用journalctl,但通常与systemctl配合)
sudo journalctl -u nginx.service

# 实时查看日志
sudo journalctl -u nginx.service -f

# 查看指定时间段的日志
sudo journalctl -u nginx.service --since "2024-01-01" --until "2024-01-02"

# 查看内核日志
sudo journalctl -k

# 查看系统启动日志
sudo journalctl -b

示例8:系统电源管理

# 重启系统
sudo systemctl reboot

# 关机
sudo systemctl poweroff

# 挂起系统
sudo systemctl suspend

# 休眠系统
sudo systemctl hibernate

# 混合休眠
sudo systemctl hybrid-sleep

# 取消关机/重启(在延迟执行的情况下)
sudo systemctl cancel

八、实用技巧

1. 批量管理服务

#!/bin/bash
# 批量重启所有Web服务
SERVICES=("nginx" "apache2" "httpd")

for SERVICE in "${SERVICES[@]}"; do
    if systemctl is-active "$SERVICE" &> /dev/null; then
        echo "重启 $SERVICE..."
        sudo systemctl restart "$SERVICE"
    fi
done

2. 服务健康检查脚本

#!/bin/bash
# 服务健康检查脚本
CHECK_SERVICES=("nginx" "mysql" "redis" "postgresql")

for SERVICE in "${CHECK_SERVICES[@]}"; do
    if systemctl is-active "$SERVICE" &> /dev/null; then
        echo "✓ $SERVICE 运行正常"
    else
        echo "✗ $SERVICE 未运行"
        # 尝试自动恢复
        sudo systemctl start "$SERVICE"
        if [ $? -eq 0 ]; then
            echo "  → 已启动 $SERVICE"
        fi
    fi
done

3. 自动清理失败的服务

#!/bin/bash
# 自动清理失败的服务
FAILED_SERVICES=$(systemctl list-units --type=service --state=failed --no-legend | awk '{print $1}')

if [ -z "$FAILED_SERVICES" ]; then
    echo "没有失败的服务"
    exit 0
fi

echo "发现失败的服务:"
echo "$FAILED_SERVICES"
echo ""
echo "尝试重置并重启..."

for SERVICE in $FAILED_SERVICES; do
    echo "处理 $SERVICE..."

    # 重置失败状态
    sudo systemctl reset-failed "$SERVICE"

    # 尝试重启
    sudo systemctl start "$SERVICE"

    # 检查结果
    if systemctl is-active "$SERVICE" &> /dev/null; then
        echo "  ✓ $SERVICE 已恢复"
    else
        echo "  ✗ $SERVICE 仍然失败"
    fi
done

4. 服务资源监控

#!/bin/bash
# 监控服务资源使用情况
MONITOR_SERVICES=("nginx" "mysql")

while true; do
    clear
    echo "服务资源监控 - $(date)"
    echo "=============================="

    for SERVICE in "${MONITOR_SERVICES[@]}"; do
        echo ""
        echo "服务: $SERVICE"

        # 获取服务状态
        STATUS=$(systemctl is-active "$SERVICE" 2>/dev/null)
        if [ "$STATUS" = "active" ]; then
            # 获取主进程ID
            MAIN_PID=$(systemctl show -p MainPID "$SERVICE" --value)

            if [ "$MAIN_PID" -ne 0 ]; then
                # 获取内存使用(RSS)
                MEM_KB=$(ps -o rss= -p "$MAIN_PID" | awk '{print $1}')
                MEM_MB=$((MEM_KB / 1024))

                # 获取CPU使用率
                CPU=$(ps -o %cpu= -p "$MAIN_PID" | awk '{print $1}')

                echo "  状态: 运行中"
                echo "  PID: $MAIN_PID"
                echo "  内存: ${MEM_MB}MB"
                echo "  CPU: ${CPU}%"
            fi
        else
            echo "  状态: $STATUS"
        fi
    done

    sleep 5
done

5. 服务配置文件生成器

#!/bin/bash
# 简单的systemd服务文件生成器
SERVICE_NAME="$1"
USER="$2"
EXEC_START="$3"
WORKING_DIR="$4"
DESCRIPTION="$5"

if [ -z "$SERVICE_NAME" ]; then
    echo "用法: $0 <服务名> <用户> <执行命令> [工作目录] [描述]"
    exit 1
fi

cat > "/tmp/${SERVICE_NAME}.service" << EOF
[Unit]
Description=${DESCRIPTION:-${SERVICE_NAME} Service}
After=network.target

[Service]
Type=simple
User=${USER:-root}
WorkingDirectory=${WORKING_DIR:-/}
ExecStart=${EXEC_START}
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

echo "服务文件已生成: /tmp/${SERVICE_NAME}.service"
echo "请检查并复制到 /etc/systemd/system/"

6. 系统启动时间优化

#!/bin/bash
# 分析系统启动时间
echo "=== 系统启动时间分析 ==="

# 查看系统启动时间
systemd-analyze

echo ""
echo "=== 各服务启动时间 ==="
systemd-analyze blame | head -20

echo ""
echo "=== 启动关键路径 ==="
systemd-analyze critical-chain

echo ""
echo "=== 生成启动图表 ==="
# 生成SVG图表(需要graphviz)
systemd-analyze plot > /tmp/boot-analysis.svg
echo "图表已保存到: /tmp/boot-analysis.svg"

九、systemd单元文件详解

服务文件示例分析

[Unit]
Description=My Application       # 服务描述
Documentation=https://example.com/docs  # 文档链接
Requires=network.target          # 强依赖(必须成功)
Wants=mysql.service              # 弱依赖(可选)
After=network.target mysql.service  # 启动顺序
Before=nginx.service             # 在其他服务之前启动
Conflicts=old-app.service        # 冲突的服务
ConditionPathExists=/opt/myapp/config.conf  # 条件检查

[Service]
Type=simple                      # 服务类型:simple, forking, oneshot, dbus, notify
User=appuser                     # 运行用户
Group=appgroup                   # 运行组
WorkingDirectory=/opt/myapp      # 工作目录
ExecStart=/usr/bin/myapp start   # 启动命令
ExecStop=/usr/bin/myapp stop     # 停止命令
ExecReload=/usr/bin/myapp reload # 重载命令
Restart=on-failure               # 重启策略:no, on-success, on-failure, on-abnormal, on-watchdog, on-abort, always
RestartSec=10                    # 重启间隔(秒)
Environment="KEY=value"          # 环境变量
EnvironmentFile=/etc/myapp.conf  # 环境变量文件
StandardOutput=journal           # 标准输出:inherit, null, tty, journal, syslog, kmsg
StandardError=journal            # 标准错误
PrivateTmp=true                  # 使用私有/tmp
ProtectSystem=full               # 文件系统保护
NoNewPrivileges=true             # 禁止获取新权限

[Install]
WantedBy=multi-user.target       # 安装到哪个target
Also=myapp-socket.service        # 同时安装的其他单元
Alias=myapp.service              # 别名

十、常见问题

Q: systemctl start和enable有什么区别?

A: 主要区别:

  • systemctl start:立即启动服务
  • systemctl enable:设置服务在系统启动时自动启动
  • systemctl stop:立即停止服务
  • systemctl disable:禁止服务在系统启动时自动启动

通常两者结合使用:sudo systemctl enable --now nginx(立即启动并设置开机自启)

Q: 如何查看服务的完整日志?

A: 使用 journalctl 命令查看服务日志:

# 查看特定服务的日志
sudo journalctl -u nginx.service

# 实时查看日志
sudo journalctl -u nginx.service -f

# 查看指定时间段的日志
sudo journalctl -u nginx.service --since "1 hour ago"

# 查看错误日志
sudo journalctl -u nginx.service -p err

# 查看完整的日志(包括所有字段)
sudo journalctl -u nginx.service -o json-pretty
Q: 服务启动失败如何调试?

A: 调试步骤:

  1. 查看服务状态:systemctl status service-name
  2. 查看详细日志:journalctl -u service-name -xe
  3. 手动测试执行命令:sudo -u user /path/to/command
  4. 检查依赖服务:systemctl list-dependencies service-name
  5. 检查配置文件语法:systemd-analyze verify /path/to/service-file
  6. 启用调试模式:在服务文件中添加 Environment=SYSTEMD_LOG_LEVEL=debug
Q: 如何创建自定义定时器?

A: 创建定时器文件,例如 /etc/systemd/system/daily-backup.timer

[Unit]
Description=Daily Backup Timer

[Timer]
OnCalendar=daily              # 每天执行
Persistent=true               # 如果错过执行时间,下次启动时立即执行
Unit=daily-backup.service     # 关联的服务

[Install]
WantedBy=timers.target

然后创建对应的服务文件并启用:

sudo systemctl enable daily-backup.timer
sudo systemctl start daily-backup.timer
Q: systemctl daemon-reload 什么时候使用?

A: 在以下情况下需要使用:

  1. 修改了任何 systemd 单元文件(.service, .timer, .mount 等)
  2. 添加了新的单元文件
  3. 删除了单元文件
  4. 修改了 systemd 配置文件(如 /etc/systemd/system.conf

注意:daemon-reload 不会重启正在运行的服务,只会重新加载配置。如果需要应用配置更改,可能还需要重启服务。

注意事项:
  • 生产环境中修改服务配置前,先进行备份和测试
  • 避免直接编辑 /usr/lib/systemd/system/ 中的文件,应在 /etc/systemd/system/ 中创建覆盖文件
  • 理解服务依赖关系,避免循环依赖
  • 定期检查失败的服务和系统日志
  • 使用 systemd-analyze 工具优化启动时间
最佳实践:
  • 为每个服务创建专用用户,提高安全性
  • 使用 Type=forking 时,正确设置 PIDFile
  • 合理设置资源限制(如CPU、内存、文件描述符)
  • 使用 ProtectSystem=strictProtectHome=true 增强安全性
  • 为关键服务配置监控和告警