亲测有效!用systemd实现脚本开机自动运行全过程

1. 引言:为什么选择 systemd 管理开机脚本

在 Linux 系统运维和嵌入式开发中,经常需要让自定义脚本在系统启动时自动运行。无论是初始化硬件设备、启动后台服务,还是配置网络环境,手动执行显然不现实。传统的 rc.local 方式虽然简单,但在现代 Linux 发行版中已被逐步弃用或限制。

systemd 作为当前主流 Linux 系统的初始化系统(init system),提供了强大且标准化的服务管理机制。通过编写一个 .service 文件,我们可以精确控制脚本的启动时机、运行用户、失败重启策略等关键参数。

本文将基于实际测试经验,完整演示如何使用 systemd 实现脚本的开机自动运行,涵盖服务文件创建、权限配置、状态检查与日志调试等核心环节,确保方案“亲测有效”。


2. 准备工作与环境说明

2.1 前置条件

  • 操作系统:支持 systemd 的 Linux 发行版(如 Ubuntu、Debian、CentOS、Armbian 等)
  • 权限要求:具备 sudo 权限
  • 脚本路径:假设目标脚本位于 /home/orangepi/mjpg.sh
  • 脚本功能:以启动 MJPG-Streamer 视频流服务为例(可替换为任意自定义脚本)

2.2 脚本基础要求

确保你的脚本满足以下条件:

  • 具备可执行权限: bash chmod +x /home/orangepi/mjpg.sh
  • 包含正确的解释器声明(shebang): bash #!/bin/bash
  • 若涉及硬件访问(如摄像头),需确认运行用户有相应设备权限(如加入 video 组)。

3. 创建 systemd 服务单元文件

3.1 服务文件命名规范

systemd 服务文件通常以 .service 结尾,存放于 /etc/systemd/system/ 目录下。该目录用于管理员自定义服务,优先级高于系统默认配置。

建议命名格式:<功能名>.service,例如 mjpg.servicestartup-script.service

执行命令创建服务文件:

sudo nano /etc/systemd/system/mjpg.service

3.2 编写服务配置内容

将以下内容写入 mjpg.service 文件:

[Unit]
Description=Start mjpg.sh at boot
After=network.target

[Service]
Type=simple
ExecStart=/bin/bash /home/orangepi/mjpg.sh
Restart=on-failure
RestartSec=5
User=orangepi
Group=orangepi
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

3.3 配置项详解

配置段 关键指令 说明
[Unit] Description 服务描述,便于识别用途
After=network.target 表示在网络服务启动后才运行此脚本,适用于依赖网络的功能
[Service] Type=simple 默认类型,主进程即为 ExecStart 指定的命令
ExecStart 指定要执行的脚本完整路径,推荐使用 /bin/bash 显式调用
Restart=on-failure 仅在失败时重启,避免无限循环
RestartSec=5 失败后等待 5 秒再尝试重启
UserGroup 指定运行脚本的非 root 用户,提升安全性
StandardOutput/StandardError 将输出重定向至 journal 日志系统,便于排查问题
[Install] WantedBy=multi-user.target 表示在多用户文本模式下启用该服务

重要提示:请根据实际情况修改 UserGroup 和脚本路径。若脚本必须以 root 运行,可省略 UserGroup


4. 加载并启用 systemd 服务

4.1 重新加载 systemd 配置

每次新增或修改 .service 文件后,必须通知 systemd 重新读取配置:

sudo systemctl daemon-reload

这一步是必须的,否则后续操作会失败或无效。

4.2 启用服务(设置开机自启)

启用服务意味着将其链接到启动目标(multi-user.target),从而实现开机自动运行:

sudo systemctl enable mjpg.service

成功后输出类似:

Created symlink /etc/systemd/system/multi-user.target.wants/mjpg.service → /etc/systemd/system/mjpg.service.

4.3 手动启动服务进行测试

在重启前,先手动启动服务验证是否正常工作:

sudo systemctl start mjpg.service

查看服务是否正在运行:

sudo systemctl status mjpg.service

预期输出应包含: - active (running) 状态 - 正确的 PID 和启动时间 - 最近的日志片段

示例输出节选:

● mjpg.service - Start mjpg.sh at boot
     Loaded: loaded (/etc/systemd/system/mjpg.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2025-04-05 10:30:22 CST; 1min ago
   Main PID: 1234 (bash)
      Tasks: 3 (limit: 4915)
     Memory: 2.1M
     CGroup: /system.slice/mjpg.service
             ├─1234 /bin/bash /home/orangepi/mjpg.sh
             └─1235 ./mjpg_streamer -o output_http.so -i input_uvc.so

5. 故障排查与日志分析

即使配置正确,脚本仍可能因路径、权限或依赖问题无法启动。systemd 提供了强大的日志工具帮助定位问题。

5.1 查看服务日志

使用 journalctl 查看指定服务的所有日志:

sudo journalctl -u mjpg.service

常用参数组合:

  • 查看最近 20 行日志: bash sudo journalctl -u mjpg.service -n 20

  • 实时跟踪日志输出(类似 tail -f): bash sudo journalctl -u mjpg.service -f

  • 查看上次启动的日志(适用于已重启过的系统): bash sudo journalctl -u mjpg.service --boot=-1

5.2 常见问题及解决方案

❌ 问题1:Failed at step EXEC spawning... Permission denied

原因:脚本无执行权限或 SELinux/AppArmor 限制。

解决方法:

chmod +x /home/orangepi/mjpg.sh
❌ 问题2:脚本路径中的环境变量未生效(如 $HOME

原因:systemd 不加载 shell 环境变量。

解决方法:在脚本中显式定义所需变量,或使用绝对路径。

❌ 问题3:服务启动过早,依赖资源尚未就绪

原因:缺少 After=Wants= 设置不当。

改进方案:根据依赖添加如下配置:

After=network.target sound.target video4linux.target
❌ 问题4:脚本启动后立即退出,状态显示 inactive (dead)

原因:Type=simple 下,主进程退出即视为服务结束。

解决方法: - 改为 Type=forking 并配合 PIDFile=(适用于守护进程) - 或在脚本末尾添加阻塞命令(如 sleep infinitywait 等)

示例改进脚本结尾:

# Keep script alive to maintain service running state
wait

6. 验证开机自启效果

完成所有配置后,建议进行真实重启测试:

sudo reboot

系统重启后,登录终端并检查服务状态:

systemctl status mjpg.service

如果显示 active (running),并且日志中能看到脚本成功执行的记录,则说明开机自启已成功实现。


7. 总结

通过本文的实践流程,我们系统地实现了使用 systemd 管理脚本开机自动运行的目标。相比传统方式,systemd 提供了更精细的控制能力和更强的稳定性保障。

核心要点回顾

  1. 服务文件位置:自定义服务应放在 /etc/systemd/system/ 目录。
  2. 配置完整性:合理设置 DescriptionAfterUserRestart 等字段。
  3. 权限与路径:确保脚本可执行,路径使用绝对地址。
  4. 重载配置:修改服务文件后务必执行 daemon-reload
  5. 启用服务:使用 enable 命令注册开机启动。
  6. 日志调试:善用 journalctl -u <service> 快速定位问题。

该方法已在多种 ARM 开发板(如 Orange Pi、Raspberry Pi)和 x86 服务器上验证有效,适用于物联网设备初始化、边缘计算节点部署等多种场景。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐