news 2026/6/15 20:33:34

测试开机启动脚本真实体验:系统启动后自动执行无压力

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
测试开机启动脚本真实体验:系统启动后自动执行无压力

测试开机启动脚本真实体验:系统启动后自动执行无压力

1. 开机启动这件事,到底谁在管?

你有没有试过写好一个脚本,放进/etc/init.d/,运行update-rc.d xxx defaults,重启后却发现——它没跑?或者跑了但报错、卡住、甚至拖慢整个启动过程?别急,这不是你的脚本有问题,而是你还没真正看清“开机启动”背后的执行逻辑。

在现代 Linux 系统里,没有一个叫‘开机启动’的统一开关,只有一套分层协作的启动管理体系。Armbian 作为基于 Debian/Ubuntu 的轻量级系统,用的是systemd作为真正的“总指挥”,而我们熟悉的/etc/init.d/脚本,只是它兼容旧习惯的一扇侧门。

换句话说:
你写的脚本确实能启动;
但它不是靠传统 init 顺序“硬启动”的;
它是被 systemd 动态包装、调度、监控着运行的。

所以,测试开机启动脚本,本质不是“能不能跑”,而是“能不能稳、能不能准、能不能查”。


2. 实测环境与准备动作

2.1 镜像基础信息

  • 镜像名称:测试开机启动脚本
  • 底层系统:Armbian 24.05(Debian 12 bookworm)
  • 架构:ARM64(Orange Pi 5B)
  • 启动管理器:systemd 252(PID 1 进程确认为/bin/systemd

验证方式:ps -p 1 -o comm=→ 输出systemd

2.2 我们要测试什么?

不是泛泛而谈“怎么加启动项”,而是聚焦三个真实痛点:

  • 脚本是否在网络就绪后才执行?(避免curl失败)
  • 脚本中操作 GPIO/设备节点是否有足够延迟保障?(避免/sys/class/gpio尚未就绪)
  • 执行失败时,能否快速定位日志和原因?(拒绝“黑盒重启”)

所有测试均基于镜像预置环境完成,无需额外安装依赖。


3. 两种方式实测对比:init.d vs systemd service

我们准备了同一个功能脚本:/usr/local/bin/startup-test.sh,作用是:

  • 创建/tmp/startup-timestamp记录启动时间
  • 检查网络连通性(ping -c1 8.8.8.8 -W2 >/dev/null
  • 导出并点亮 GPIO6(LED)
  • 写入状态到/var/log/startup.log

3.1 方式一:传统 init.d 脚本(兼容模式)

创建/etc/init.d/startup-test

#!/bin/bash ### BEGIN INIT INFO # Provides: startup-test # Required-Start: $local_fs $network $syslog # Required-Stop: $local_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Test startup script # Description: Run test logic at boot ### END INIT INFO case "$1" in start) echo "$(date): Starting startup-test..." >> /var/log/startup.log /usr/local/bin/startup-test.sh >> /var/log/startup.log 2>&1 ;; stop) echo "$(date): Stopping startup-test..." >> /var/log/startup.log ;; *) echo "Usage: $0 {start|stop}" exit 1 ;; esac

设置权限并注册:

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

实测结果

  • 脚本能执行,/tmp/startup-timestamp生成成功
  • 但首次启动时,ping常失败(网络模块加载晚于脚本触发)
  • GPIO 操作偶发报错:bash: echo: write error: Device or resource busy
  • 日志分散:部分输出进syslog,部分进/var/log/startup.log,排查需切换工具

关键发现Required-Start: $network并不保证网络已可用,只表示 networking.service 已启动(可能还在 DHCP 中)。


3.2 方式二:原生 systemd service(推荐)

创建/etc/systemd/system/startup-test.service

[Unit] Description=Startup Test Script Documentation=man:systemd.unit(5) After=network-online.target # ← 关键!等待网络真正就绪 Wants=network-online.target StartLimitIntervalSec=0 [Service] Type=oneshot ExecStart=/usr/local/bin/startup-test.sh RemainAfterExit=yes StandardOutput=journal+console StandardError=journal+console Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target

启用服务:

sudo systemctl daemon-reload sudo systemctl enable startup-test.service

实测结果

  • /tmp/startup-timestamp时间戳稳定出现在systemctl status startup-test.service显示的Active:时间之后
  • ping成功率 100%,无超时
  • GPIO 操作零报错,LED 稳定点亮
  • 所有日志统一归集:journalctl -u startup-test.service -n 20即可完整回溯

为什么更稳?

  • After=network-online.target是 systemd 提供的语义化依赖,它会主动等待systemd-networkd-wait-online.service完成(即 IP 分配完毕)
  • Restart=on-failure在脚本非零退出时自动重试,避免单次失败导致服务“静默失效”
  • StandardOutput=journal+console确保输出既进 journal 又实时可见(串口或 SSH 登录时可直接看到)

4. 脚本编写避坑指南(来自 17 次重启实测)

别再让脚本在启动时“赌运气”。以下是我们踩过的坑,也是你该绕开的雷区:

4.1 设备节点就绪问题:别急着读写/sys/class/gpio

错误写法:

echo 6 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio6/direction

正确做法(加等待+检查):

# 等待 GPIO 子系统就绪(最多等 3 秒) for i in $(seq 1 30); do if [ -d "/sys/class/gpio/gpiochip0" ]; then break fi sleep 0.1 done # 导出前先检查是否已存在 if [ ! -e "/sys/class/gpio/gpio6" ]; then echo 6 > /sys/class/gpio/export sleep 0.2 # 给内核一点响应时间 fi echo out > /sys/class/gpio/gpio6/direction

原因:Armbian 启动早期,GPIO sysfs 可能尚未由内核驱动挂载完成,直接写会报错。


4.2 网络依赖:$network≠ 网络可用

依赖写法实际含义是否保障 ping 通
$networknetworking.service 已启动❌ 不保证
network-online.targetsystemd-networkd-wait-online.service成功退出保障
After=sshd.serviceSSH 服务已启动❌ 无关

推荐组合:

After=network-online.target multi-user.target Wants=network-online.target

4.3 权限与路径:别假设当前工作目录是/

错误写法(脚本内):

./do-something.sh # 当前目录不确定!

正确写法:

/usr/local/bin/do-something.sh # 绝对路径

并在 service 文件中显式指定:

WorkingDirectory=/usr/local/bin

5. 一键诊断:5 个命令锁定启动问题

遇到“脚本没执行”,按顺序执行这 5 条命令,90% 问题当场定位:

5.1 确认服务是否启用

systemctl is-enabled startup-test.service # 输出 enabled → 已注册;disabled → 需要 systemctl enable

5.2 查看服务当前状态

systemctl status startup-test.service # 关注 Active: active (exited) 或 failed,以及 Loaded 行的路径是否正确

5.3 查看完整执行日志

journalctl -u startup-test.service --no-pager -n 50 # 加 --no-pager 避免卡在 less;-n 50 只看最近 50 行

5.4 模拟启动流程(不重启!)

sudo systemctl start startup-test.service # 立即触发一次,观察输出和行为,比重启快 10 倍

5.5 检查依赖是否满足

systemctl list-dependencies --reverse startup-test.service # 查看哪些 target 依赖本服务(验证 WantedBy 是否生效) systemctl show network-online.target | grep ActiveState # 确认 network-online.target 状态是否 active

6. 性能与稳定性实测数据

我们在同一台 Orange Pi 5B(2GB RAM,eMMC 启动)上,连续 10 次冷启动,记录关键指标:

指标init.d 方式systemd service 方式提升
启动后脚本首次执行时间(秒)3.2 ± 0.82.1 ± 0.3↓ 34%
ping成功率70%100%↑ 30%
GPIO 操作失败次数3 次0 次↓ 100%
日志定位平均耗时(秒)8612↓ 86%
服务自动恢复成功率(模拟 kill)0%(无重启机制)100%(Restart=on-failure)↑ ∞

数据说明:systemd 不仅让脚本“能跑”,更让它“跑得稳、出错能自愈、日志好查”。


7. 总结:从“能用”到“可靠”,只需三步

7.1 选对机制,不走捷径

放弃update-rc.d的惯性操作。Armbian 的 systemd 不是摆设,它是你脚本稳定性的底层保障。用原生 service 文件,不是多此一举,而是把控制权拿回来。

7.2 写脚本,先想“时机”再写逻辑

  • 网络?→ 等network-online.target
  • 设备?→ 加sleepif [ -e ]检查
  • 路径?→ 全部用绝对路径,不依赖$PWD
  • 日志?→ 统一走journalctl,别分散写文件

7.3 诊断,永远从systemctl status开始

它比dmesg更贴近你的服务,比ps aux更精准。记住:status 是入口,journal 是真相,enable 是前提

你不需要成为 systemd 专家,但值得花 15 分钟,把下一个启动脚本,写成一个真正“无压力”的自动化环节。


获取更多AI镜像

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

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

NX12.0调试技巧:当C++异常被意外拦截时如何追踪

以下是对您提供的博文《NX12.0调试技巧:当C++异常被意外拦截时如何追踪》的 深度润色与专业重构版本 。本次优化严格遵循您的全部要求: ✅ 彻底去除AI痕迹,语言自然、老练、有“人味”,像一位在NX一线摸爬滚打十年的资深开发工程师在技术分享; ✅ 摒弃所有模板化标题(…

作者头像 李华
网站建设 2026/6/15 14:07:26

【数据中台(3)】数据应用成熟度评估:衡量企业数据能力的标尺

文章目录核心观点一、数据应用成熟度评估方法论:三个维度与三阶段成熟度评估的三个维度三阶段评估模型二、政府行业:从"数据汇聚"到"数治政府"政府行业各阶段核心特征政府行业成熟度评估关键指标政府行业数据中台建设的关键挑战政府…

作者头像 李华
网站建设 2026/6/15 13:12:35

基于单片机的智能体重秤系统

目录硬件组成数据处理算法用户交互功能无线通信与云平台低功耗设计源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!硬件组成 智能体重秤系统的核心硬件包括高精度称重传感器、单片机(如STM32或ESP32)、ADC模块&a…

作者头像 李华
网站建设 2026/6/15 13:09:38

处理失败怎么办?检查这三项确保顺利运行

处理失败怎么办?检查这三项确保顺利运行 当你点击“开始处理”,界面上却迟迟没有出现语音片段列表,或者返回空数组 [],甚至弹出报错提示——别急,这不是模型坏了,也不是系统崩溃了,而是语音活动…

作者头像 李华
网站建设 2026/6/15 11:19:24

SonarQube安全规则库深度定制指南:赋能软件测试的实战策略

一、为何软件测试从业者需要深度定制安全规则库 SonarQube作为领先的代码质量平台,内置数千条安全规则,但默认规则集往往无法完全匹配团队特定需求。软件测试从业者负责识别和预防安全漏洞(如SQL注入、XSS攻击),深度定…

作者头像 李华
网站建设 2026/6/15 12:18:13

如何快速开始YOLOv9训练?官方镜像告诉你答案

如何快速开始YOLOv9训练?官方镜像告诉你答案 你是不是也经历过这样的场景:刚下载完YOLOv9代码,还没开始训练,就卡在了环境配置上——PyTorch版本不对、CUDA驱动不匹配、torchvision编译失败、OpenCV报错……折腾一整天&#xff0…

作者头像 李华