news 2026/4/23 17:55:20

Armbian下如何正确配置开机启动?答案在这里

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Armbian下如何正确配置开机启动?答案在这里

Armbian下如何正确配置开机启动?答案在这里

1. 理解Armbian的启动机制本质

1.1 systemd才是真正的主角

Armbian基于Debian或Ubuntu,从内核加载完成后的第一个进程(PID 1)就是/bin/systemd。这不是可选项,而是系统默认且唯一的核心启动管理器。所有你看到的/etc/init.d/脚本、rc.local、甚至传统SysV风格的启动流程,本质上都是systemd通过兼容层模拟执行的。

你可以用最直接的方式验证:

ps -p 1 -o comm=

输出结果一定是:

systemd

这说明整个启动生命周期——从硬件初始化到用户服务就绪——都由systemd统一调度、依赖解析和状态管理。它不是“支持”systemd,而是“只运行”systemd。

1.2 init.d只是systemd的翻译官

当你把一个脚本放进/etc/init.d/并执行update-rc.d xxx defaults时,systemd并不会真的去读取/etc/rc2.d/S01xxx这样的符号链接。相反,它会动态生成一个临时的unit文件(类似/run/systemd/generator.late/gpio-init.sh.service),将你的脚本包装成一个符合systemd规范的服务单元,并纳入其依赖图中。

这意味着:

  • 脚本的启动顺序不再由S01/S02数字决定,而是由After=Wants=等依赖声明控制;
  • systemctl restart gpio-init.sh能成功,是因为systemd在背后做了完整的服务生命周期封装;
  • 日志全部归入journalctl -u gpio-init.sh,而不是分散在/var/log/里。

所以,别再把init.d当作“原生方式”——它只是systemd为你保留的一扇后门,方便过渡,但绝非最佳实践。

2. 查看当前所有开机启动项的权威方法

2.1 查看真正启用的systemd服务(推荐)

这是最准确、最现代的方式,直接反映systemd的决策结果:

systemctl list-unit-files --type=service --state=enabled

你会看到类似输出:

ssh.service enabled networking.service enabled cron.service enabled gpio-init.service enabled bluetooth.service disabled

注意:enabled表示该服务已注册为开机自启,与是否正在运行无关。如果想确认当前是否活跃,加一个--state=running

systemctl --type=service --state=running | grep -E "(gpio|network|ssh)"

2.2 检查init.d脚本的“伪装身份”

虽然init.d脚本被systemd接管,但它们仍保留在/etc/rc*.d/目录下。查看它们的存在,只是为了确认兼容层是否生效:

ls /etc/rc2.d/ | grep -E "S[0-9]{2}"

输出可能包括:

S01gpio-init.sh S02networking S03cron

但这串S01编号对systemd完全无效。systemd忽略这些数字,只认/etc/init.d/gpio-init.sh脚本内部的LSB头注释(如# Required-Start: $local_fs),并将其转换为After=local-fs.target。因此,不要试图靠改名来调整顺序——那是徒劳的。

2.3 透视整个启动依赖树

想看清服务之间的因果关系?用这个命令一目了然:

systemctl list-dependencies --all --no-pager multi-user.target

它会展示从multi-user.target(标准多用户模式)出发,所有被直接或间接依赖的unit,形成一棵清晰的树状图。你会发现gpio-init.service很可能排在networking.service之后,而cron.service又依赖于timers.target——这才是systemd真正理解的启动逻辑。

3. 正确创建开机启动服务的两种路径

3.1 推荐方案:原生systemd service(强烈建议)

这是面向未来的写法,可控、可查、可维护。以“测试开机启动脚本”为例,我们创建一个名为test-boot-script.service的服务。

第一步:编写service文件

sudo nano /etc/systemd/system/test-boot-script.service

内容如下(请逐行理解每段含义):

[Unit] Description=Test Boot Script for GPIO Control After=multi-user.target Wants=multi-user.target [Service] Type=oneshot ExecStart=/usr/local/bin/test-boot-script.sh RemainAfterExit=yes User=root Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin [Install] WantedBy=multi-user.target

关键点说明:

  • After=multi-user.target:确保在基础系统服务就绪后再运行;
  • Type=oneshot:表示这是一个一次性执行脚本,不常驻后台;
  • RemainAfterExit=yes:即使脚本执行完毕,systemd也认为该服务“仍在运行”,便于后续状态查询;
  • User=root:明确指定执行用户,避免权限问题;
  • Environment=PATH=...:显式设置PATH,防止脚本因找不到echosh等命令而失败。

第二步:准备实际脚本

sudo nano /usr/local/bin/test-boot-script.sh

内容(精简、健壮、带错误检查):

#!/bin/bash # 测试开机启动脚本:点亮GPIO6 LED # 检查GPIO是否已导出,避免重复操作 if [ ! -d "/sys/class/gpio/gpio6" ]; then echo 6 > /sys/class/gpio/export 2>/dev/null sleep 0.1 fi # 设置方向为输出 echo out > /sys/class/gpio/gpio6/direction 2>/dev/null # 点亮LED(高电平) echo 1 > /sys/class/gpio/gpio6/value 2>/dev/null # 可选:记录日志到journal logger "test-boot-script: GPIO6 LED turned ON at boot"

赋予执行权限:

sudo chmod +x /usr/local/bin/test-boot-script.sh

第三步:启用并测试

# 重新加载unit定义(必须!) sudo systemctl daemon-reload # 启用开机自启 sudo systemctl enable test-boot-script.service # 立即运行一次(不重启也可验证) sudo systemctl start test-boot-script.service # 检查状态和日志 sudo systemctl status test-boot-script.service sudo journalctl -u test-boot-script.service -n 20 --no-pager

3.2 兼容方案:init.d脚本(仅限遗留场景)

如果你必须沿用旧脚本结构,或团队有统一init.d规范,请严格遵循LSB(Linux Standard Base)标准。

创建脚本:

sudo nano /etc/init.d/test-boot-script

内容(注意开头的LSB注释块):

#!/bin/bash ### BEGIN INIT INFO # Provides: test-boot-script # Required-Start: $local_fs $network # Required-Stop: $local_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Test boot script for GPIO # Description: Initialize GPIO pins at system boot ### END INIT INFO case "$1" in start) echo "Starting test-boot-script..." # 实际启动逻辑 if [ ! -d "/sys/class/gpio/gpio6" ]; then echo 6 > /sys/class/gpio/export fi echo out > /sys/class/gpio/gpio6/direction echo 1 > /sys/class/gpio/gpio6/value logger "test-boot-script started" ;; stop) echo "Stopping test-boot-script..." echo 0 > /sys/class/gpio/gpio6/value echo 6 > /sys/class/gpio/unexport logger "test-boot-script stopped" ;; restart) $0 stop $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0

设置权限并注册:

sudo chmod +x /etc/init.d/test-boot-script sudo update-rc.d test-boot-script defaults

验证是否被systemd识别:

systemctl status test-boot-script

你会看到类似Loaded: loaded (/etc/init.d/test-boot-script; generated)的提示,证明systemd已成功接管。

4. 常见陷阱与避坑指南

4.1 “脚本没执行”?先查这三件事

陷阱1:PATH环境变量丢失
systemd服务默认PATH极短(通常只有/usr/bin:/bin)。如果你的脚本调用了/usr/local/bin/gpio-tool,它会报“command not found”。
解决:在service文件中显式设置Environment=PATH=...,或在脚本内使用绝对路径。

陷阱2:GPIO设备未就绪
/sys/class/gpio/在早期启动阶段可能尚未挂载,直接echo 6 > /sys/class/gpio/export会失败。
解决:添加After=sysfs.targetAfter=local-fs.target,并在脚本中加入重试逻辑(如for i in {1..5}; do ... sleep 0.2; done)。

陷阱3:权限不足
普通用户无法写入/sys/class/gpio/。即使脚本是root用户,若未在service中声明User=root,systemd会以nobody运行。
解决:service文件中必须包含User=root,且ExecStart路径需可被root访问。

4.2 日志调试:别再靠echo到文件

很多教程教你在脚本里写echo "debug" >> /tmp/boot.log,这既不安全也不可靠。
正确做法:用logger命令将消息写入systemd journal:

logger "test-boot-script: Setting GPIO6 direction to out"

然后用以下命令实时追踪:

sudo journalctl -f -u test-boot-script.service

或者查看完整历史:

sudo journalctl -u test-boot-script.service --since "1 hour ago"

4.3 服务冲突:多个脚本争抢同一个GPIO

如果你同时启用了gpio-init.servicetest-boot-script.service,两者都试图控制gpio6,可能导致不可预测行为。
解决:用Conflicts=声明互斥关系:

[Unit] Conflicts=gpio-init.service

这样当一个服务启动时,另一个会自动停止。

5. 验证与故障排查全流程

5.1 重启前的最终检查清单

在执行sudo reboot之前,请务必完成以下验证:

  1. 语法检查

    sudo systemd-analyze verify /etc/systemd/system/test-boot-script.service
  2. 依赖解析

    sudo systemd-analyze dot test-boot-script.service | dot -Tpng > deps.png

    (需安装graphviz,生成依赖图直观查看)

  3. 模拟启动

    sudo systemd-run --scope --on-boot=test-boot-script.service /usr/local/bin/test-boot-script.sh
  4. 手动触发测试

    sudo systemctl start test-boot-script.service && sudo systemctl status test-boot-script.service

5.2 重启后快速诊断

系统启动完成后,立即运行:

# 查看该服务是否被激活 systemctl is-enabled test-boot-script.service # 应输出 enabled # 查看是否成功启动(active表示运行成功) systemctl is-active test-boot-script.service # 应输出 active # 查看详细状态和最近10行日志 sudo systemctl status test-boot-script.service -n 10 # 查看完整启动日志(过滤关键词) sudo journalctl -b | grep -i "test-boot-script\|gpio6"

如果状态是failed,重点看journalctl输出中的Failed at step ...行,它会精准指出失败环节(如EXEC表示执行失败,SETENV表示环境变量问题)。

6. 总结:选择正确的工具,事半功倍

6.1 为什么systemd service是唯一推荐方案

  • 精确控制:你能明确定义服务何时启动(After=)、依赖谁(Wants=)、失败后怎么办(Restart=on-failure);
  • 统一日志:所有输出集中到journalctl,支持时间过滤、优先级筛选、实时跟踪;
  • 状态可见systemctl status返回结构化信息,含内存占用、CPU时间、上次退出码;
  • 未来兼容:Armbian及所有主流Linux发行版将持续强化systemd生态,init.d终将退出历史舞台。

6.2 一份可直接复用的最小模板

把下面内容保存为/etc/systemd/system/your-service-name.service,替换YourDescription/path/to/your/script.sh即可开箱即用:

[Unit] Description=YourDescription After=multi-user.target Wants=multi-user.target [Service] Type=oneshot ExecStart=/path/to/your/script.sh RemainAfterExit=yes User=root Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin [Install] WantedBy=multi-user.target

然后执行三行命令:

sudo systemctl daemon-reload sudo systemctl enable your-service-name.service sudo systemctl start your-service-name.service

从此,你的Armbian设备就能在每次上电后,稳稳地执行你定义的初始化逻辑。


获取更多AI镜像

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 9:21:47

Screen to GIF多场景应用实例:演示与教学必备

以下是对您提供的博文内容进行 深度润色与结构重构后的技术博客正文 。整体风格更贴近一位资深教育技术工程师 开发者工具布道者的口吻,语言自然、逻辑严密、有温度、有洞见,彻底摆脱AI生成痕迹和教科书式刻板表达。全文已去除所有“引言/概述/总结”…

作者头像 李华
网站建设 2026/4/23 12:14:59

2026最新实测:10款论文降AI工具谁最强?附AI率95%降至5.8%真实报告

“明明是自己一个字一个字敲的,为什么知网AIGC检测还是飙红?” “为了降低ai,把论文改得面目全非,查重率不降反升,心态崩了!” 最近是定稿高峰期,后台私信全是这类惨案。现在的知网、维普算法…

作者头像 李华
网站建设 2026/4/23 10:45:04

2026知网降AI攻略:10款工具亲测对比,附AIGC率95%降至10%真实截图

如果你正在搜“免费降ai率工具”或者“论文降aigc”,那我猜你现在的心态大概率是崩的。 上来先给大家避个雷:别傻乎乎地信什么‘一键变绿’,工具选错了,比 AI 写作本身更要命。 作为一名被降ai率折磨过无数次的过来人&#xff0c…

作者头像 李华
网站建设 2026/4/23 10:46:48

从0开始运行GPT-OSS 20B:OpenAI开源模型网页版快速上手指南

从0开始运行GPT-OSS 20B:OpenAI开源模型网页版快速上手指南 你是不是也遇到过这样的困扰:想本地跑一个真正能用的大模型,结果卡在环境配置、编译报错、显存不足、界面难用这一连串问题上?好不容易搭好服务,发现连个像…

作者头像 李华
网站建设 2026/4/23 12:14:20

中英混合怎么读?GLM-TTS多语言合成实测

中英混合怎么读?GLM-TTS多语言合成实测 你有没有试过这样一段文字:“这个API的response code是200,但error log里显示‘Connection refused’”——念出来时,中文部分自然流畅,英文缩写和术语却卡顿、生硬&#xff0c…

作者头像 李华
网站建设 2026/4/23 12:22:13

STM32CubeMX下载后如何配置?入门级操作指南

以下是对您提供的博文内容进行 深度润色与结构重构后的技术文章 。本次优化严格遵循您的全部要求: ✅ 彻底去除所有AI痕迹(如模板化表达、空洞总结、机械连接词) ✅ 摒弃“引言/概述/核心特性/原理解析/实战指南/总结”等刻板标题&#x…

作者头像 李华