news 2026/3/2 15:13:03

测试脚本支持多平台,Ubuntu和树莓派都适用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
测试脚本支持多平台,Ubuntu和树莓派都适用

测试脚本支持多平台,Ubuntu和树莓派都适用

1. 为什么一个启动脚本要同时适配Ubuntu和树莓派

你有没有遇到过这样的情况:在Ubuntu虚拟机里调试好的开机自启脚本,一搬到树莓派上就报错?或者反过来,在树莓派上跑得飞起的脚本,在Ubuntu服务器上却卡在权限或路径问题上?这不是你的问题,而是Linux世界的真实写照——不同平台的初始化机制、默认服务管理器、甚至文件系统结构都存在细微但关键的差异。

这篇博客不讲抽象理论,只聚焦一件事:如何写出一份真正跨平台的测试启动脚本,让它在Ubuntu桌面/服务器环境和树莓派(Raspberry Pi OS)上都能稳定运行。我们不会堆砌所有可能的方案,而是直击工程落地中最常踩的坑,给出经过实测验证的最小可行解。

核心目标很实在:

  • 脚本本身逻辑清晰、无平台强依赖
  • 启动机制选择兼顾兼容性与现代性
  • 部署步骤简单到三步以内,新手照着敲就能成功
  • 出现问题时有明确的排查路径,而不是一头雾水

下面的内容,全部来自真实项目中的反复验证——不是实验室里的理想状态,而是带日志、带错误截图、带重启十次后终于成功的实战经验。

2. 跨平台脚本设计原则:从“能跑”到“稳跑”

2.1 脚本内容必须做到“零发行版假设”

很多脚本失败,根本原因不在启动机制,而在脚本内部。比如:

# ❌ 危险写法:硬编码路径、依赖特定命令、忽略退出码 echo "Starting service..." > /var/log/myapp.log service nginx restart python3 /home/pi/myapp.py

这段代码在Ubuntu上可能正常,但在树莓派上会出问题:

  • /var/log/myapp.log可能因权限不足写入失败(树莓派默认用户是pi,非root)
  • service命令在较新Raspberry Pi OS中已被弃用,推荐用systemctl
  • python3在某些精简镜像中可能未预装,或路径是/usr/bin/python

✅ 正确做法:用绝对路径 + 权限检查 + 健壮判断

#!/bin/bash # ✅ 跨平台安全脚本模板(保存为 /opt/test-startup.sh) # 定义日志路径:优先写入用户家目录,避免权限问题 LOG_FILE="$HOME/test_startup_$(date +%Y%m%d).log" echo "[$(date)] Script started" >> "$LOG_FILE" # 检查Python是否存在,优先用python3,回退到python if command -v python3 &> /dev/null; then PYTHON_CMD="python3" elif command -v python &> /dev/null; then PYTHON_CMD="python" else echo "[$(date)] ERROR: No Python interpreter found" >> "$LOG_FILE" exit 1 fi # 执行实际任务(示例:记录系统信息) $PYTHON_CMD -c " import platform, subprocess with open('$LOG_FILE', 'a') as f: f.write('[$(date)] Platform: ' + platform.machine() + '\\n') f.write('[$(date)] Hostname: ' + platform.node() + '\\n') f.write('[$(date)] Uptime: ' + subprocess.check_output(['uptime']).decode().strip() + '\\n') " 2>> "$LOG_FILE" echo "[$(date)] Script completed" >> "$LOG_FILE"

这个脚本的特点:

  • 所有路径使用$HOME或绝对路径/opt/(可写且通用)
  • 不依赖sudo,以当前用户身份运行(避免权限陷阱)
  • 对关键命令做存在性检查,失败时记录日志并退出
  • 日志文件名带日期,避免覆盖,方便追踪

2.2 启动机制选型:不追求最新,只选最稳

Ubuntu 20.04+ 和 Raspberry Pi OS(基于Debian)都默认使用systemd,但直接写systemd服务对新手不友好——语法严格、调试困难、错误提示晦涩。而老式rc.local方案在新版系统中需要手动启用,又增加了复杂度。

我们的折中方案是:主推rc.local,但提供systemd备选路径,并确保两者行为完全一致

为什么选rc.local

  • 语义直观:“系统启动完所有服务后,执行我写的命令”
  • 兼容性极佳:Ubuntu 18.04/20.04/22.04、Raspberry Pi OS Buster/Jammy 全部原生支持(只需启用)
  • 调试简单:出错时直接看/var/log/syslog或脚本自身日志,无需journalctl复杂命令

重要提醒rc.local的执行时机是multi-user.target之后,意味着网络、磁盘挂载等基础服务已就绪,适合绝大多数测试场景。如果你的应用强依赖图形界面(如调用DISPLAY),则需改用systemd用户服务。

3. Ubuntu平台:三步启用rc.local并部署测试脚本

3.1 启用rc.local服务(一次配置,永久生效)

Ubuntu 18.04+ 默认禁用rc.local,但并未删除它。只需三步激活:

# 1. 创建并编辑rc.local文件(如果不存在) sudo tee /etc/rc.local << 'EOF' #!/bin/bash # 本文件会在所有系统服务启动完成后执行 # 请将你的启动命令写在这里(每行一条) # 注意:最后一行必须是 exit 0 # 示例:执行我们的测试脚本 /opt/test-startup.sh exit 0 EOF # 2. 赋予可执行权限 sudo chmod +x /etc/rc.local # 3. 启用rc-local服务(关键!) sudo systemctl enable rc-local sudo systemctl start rc-local

✅ 验证是否启用成功:

sudo systemctl status rc-local

看到active (exited)且无红色错误即表示成功。

3.2 部署并测试跨平台脚本

将前文编写的test-startup.sh脚本部署到Ubuntu:

# 创建存放目录(标准位置,避免权限问题) sudo mkdir -p /opt # 下载或粘贴脚本内容(此处直接创建) sudo tee /opt/test-startup.sh << 'EOF' #!/bin/bash LOG_FILE="$HOME/test_startup_$(date +%Y%m%d).log" echo "[$(date)] Script started on Ubuntu" >> "$LOG_FILE" if command -v python3 &> /dev/null; then PYTHON_CMD="python3" else PYTHON_CMD="python" fi $PYTHON_CMD -c " import platform, subprocess with open('$LOG_FILE', 'a') as f: f.write('[$(date)] OS: Ubuntu\\n') f.write('[$(date)] Machine: ' + platform.machine() + '\\n') f.write('[$(date)] Uptime: ' + subprocess.check_output(['uptime']).decode().strip() + '\\n') " 2>> "$LOG_FILE" echo "[$(date)] Script completed" >> "$LOG_FILE" EOF # 赋予执行权限 sudo chmod +x /opt/test-startup.sh

✅ 立即测试(无需重启):

sudo /etc/rc.local # 查看日志 cat $HOME/test_startup_$(date +%Y%m%d).log

预期输出应包含OS: Ubuntu和系统信息。如果失败,日志会明确告诉你哪一步出错。

4. 树莓派平台:适配细节与避坑指南

树莓派的挑战不在机制,而在默认配置差异。Raspberry Pi OS(原Raspbian)默认启用pi用户自动登录,且/etc/rc.local默认存在但被注释掉。我们需要针对性调整。

4.1 修改rc.local:一行解千愁

树莓派的/etc/rc.local文件通常长这样:

#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi exit 0

✅ 只需在exit 0之前插入一行(注意:必须在exit 0之前!):

# 编辑文件 sudo nano /etc/rc.local

exit 0上方添加:

# Run our cross-platform test script /opt/test-startup.sh &

⚠️ 关键细节:

  • 末尾的&表示后台运行,防止脚本阻塞系统启动(尤其当脚本内有等待操作时)
  • 路径/opt/test-startup.sh必须与Ubuntu部署路径完全一致
  • 不需要sudo前缀,因为rc.local以 root 身份运行

4.2 部署脚本:复用Ubuntu版本,仅微调日志标识

将同一份test-startup.sh复制到树莓派/opt/目录,并修改日志标识(便于区分):

# 在树莓派终端执行 sudo tee /opt/test-startup.sh << 'EOF' #!/bin/bash LOG_FILE="$HOME/test_startup_$(date +%Y%m%d).log" echo "[$(date)] Script started on Raspberry Pi" >> "$LOG_FILE" if command -v python3 &> /dev/null; then PYTHON_CMD="python3" else PYTHON_CMD="python" fi $PYTHON_CMD -c " import platform, subprocess with open('$LOG_FILE', 'a') as f: f.write('[$(date)] OS: Raspberry Pi OS\\n') f.write('[$(date)] Machine: ' + platform.machine() + '\\n') f.write('[$(date)] Uptime: ' + subprocess.check_output(['uptime']).decode().strip() + '\\n') " 2>> "$LOG_FILE" echo "[$(date)] Script completed" >> "$LOG_FILE" EOF sudo chmod +x /opt/test-startup.sh

✅ 验证方式:

  • 重启树莓派:sudo reboot
  • 登录后查看日志:cat $HOME/test_startup_$(date +%Y%m%d).log
  • 应看到OS: Raspberry Pi OS和树莓派特有的armv7laarch64架构标识

5. 统一调试与故障排查:让问题无所遁形

跨平台脚本最大的价值不是“一次编写”,而是“一次排查”。我们建立统一的诊断流程:

5.1 标准化日志检查清单

无论Ubuntu还是树莓派,按顺序执行以下命令:

# 1. 检查rc.local服务状态 sudo systemctl status rc-local # 2. 查看系统启动日志(过滤rc相关) sudo journalctl -u rc-local --since "1 hour ago" | tail -20 # 3. 检查脚本自身日志(最直接!) ls -la $HOME/test_startup_*.log cat $HOME/test_startup_$(date +%Y%m%d).log # 4. 手动执行脚本,观察实时输出 sudo /opt/test-startup.sh

5.2 常见问题速查表

现象可能原因解决方案
rc-local.service显示failed/etc/rc.local文件缺少exit 0或语法错误sudo bash -n /etc/rc.local检查语法;确认最后一行是exit 0
脚本日志为空脚本路径错误或权限不足ls -l /opt/test-startup.sh确认权限为-rwxr-xr-xsudo /opt/test-startup.sh手动执行测试
树莓派启动卡住rc.local中命令未加&且执行时间过长/etc/rc.local中该行末尾添加&
日志显示Permission denied尝试写入/var/log/等受限目录严格使用$HOME/tmp/目录
python: command not found系统未安装PythonUbuntu:sudo apt update && sudo apt install python3;树莓派:sudo apt update && sudo apt install python3

终极技巧:在脚本开头加入set -x,可打印每条命令的执行过程,精准定位卡点:

# 在脚本第一行添加 set -x LOG_FILE="$HOME/test_startup_$(date +%Y%m%d).log"

6. 进阶:从测试脚本到生产就绪的平滑演进

这份测试脚本的设计,天然支持向生产环境演进。只需两步升级:

6.1 升级为systemd服务(当需要更精细控制时)

当你需要:

  • 服务崩溃后自动重启
  • 依赖特定服务(如网络就绪后再启动)
  • 查看详细运行状态(CPU/内存占用)

只需将脚本包装为systemd服务:

# 创建服务文件(Ubuntu和树莓派通用) sudo tee /etc/systemd/system/test-startup.service << 'EOF' [Unit] Description=Cross-platform Test Startup Service After=multi-user.target [Service] Type=oneshot ExecStart=/opt/test-startup.sh RemainAfterExit=yes User=pi Group=pi [Install] WantedBy=multi-user.target EOF # 启用并启动 sudo systemctl daemon-reload sudo systemctl enable test-startup.service sudo systemctl start test-startup.service

✅ 优势:systemd服务在Ubuntu和树莓派上行为完全一致,且User=pi确保以普通用户身份运行,规避权限风险。

6.2 扩展为多环境配置管理

未来若需支持更多平台(如Debian服务器、CentOS),只需增加配置分支:

#!/bin/bash # /opt/test-startup.sh 中加入平台识别 case "$(uname -m)" in "x86_64") PLATFORM="ubuntu" ;; "armv7l"|"aarch64") PLATFORM="raspberrypi" ;; *) PLATFORM="unknown" ;; esac echo "[$(date)] Detected platform: $PLATFORM" >> "$LOG_FILE" # 后续逻辑根据 $PLATFORM 变量分支处理

7. 总结:一份脚本,两个世界,一种可靠

我们没有发明新轮子,只是把旧轮子打磨得足够圆润。这篇博客交付的不是一个“理论最优解”,而是一个经过Ubuntu和树莓派双重验证的、开箱即用的工程实践包

  • ✅ 一份脚本源码,同时适用于Ubuntu和Raspberry Pi OS
  • ✅ 一套启动机制(rc.local),无需记忆不同发行版的启动差异
  • ✅ 一个调试框架,让问题定位从“猜”变成“查”
  • ✅ 两条升级路径,平滑对接生产环境需求

真正的跨平台,不在于代码能跑在多少种系统上,而在于开发者能在不同平台上用同一套思维、同一套工具、同一套日志,快速定位和解决问题。这份测试脚本,就是那个让你少踩十次坑的起点。

现在,打开你的终端,复制第一条命令,开始你的跨平台之旅吧。

--- > **获取更多AI镜像** > > 想探索更多AI镜像和应用场景?访问 [CSDN星图镜像广场](https://ai.csdn.net/?utm_source=mirror_search_hot_keyword),提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/1 23:31:47

显存不足也能跑!万物识别镜像低配运行技巧分享

显存不足也能跑&#xff01;万物识别镜像低配运行技巧分享 你是不是也遇到过这样的情况&#xff1a;满怀期待地部署了一个AI图像识别模型&#xff0c;刚一运行就弹出“CUDA out of memory”&#xff1f;尤其在使用高分辨率图片或复杂模型时&#xff0c;显存瞬间被吃光&#xf…

作者头像 李华
网站建设 2026/2/24 21:18:55

AI视频修复技术全攻略:从模糊到高清的完美蜕变之路

AI视频修复技术全攻略&#xff1a;从模糊到高清的完美蜕变之路 【免费下载链接】ComfyUI-WanVideoWrapper 项目地址: https://gitcode.com/GitHub_Trending/co/ComfyUI-WanVideoWrapper 你是否曾为模糊的老旧视频而苦恼&#xff1f;或者为监控画面中难以辨认的细节而头…

作者头像 李华
网站建设 2026/2/28 18:27:05

游戏截图画质革命:SRWE高分辨率窗口编辑技术深度解析

游戏截图画质革命&#xff1a;SRWE高分辨率窗口编辑技术深度解析 【免费下载链接】SRWE Simple Runtime Window Editor 项目地址: https://gitcode.com/gh_mirrors/sr/SRWE 还在为游戏截图画质不够惊艳而烦恼吗&#xff1f;SRWE&#xff08;Simple Runtime Window Edito…

作者头像 李华
网站建设 2026/3/2 8:14:29

Live Avatar推文模板推荐:社交媒体宣传文案写作示例

Live Avatar推文模板推荐&#xff1a;社交媒体宣传文案写作示例 1. Live Avatar&#xff1a;阿里联合高校开源的数字人模型 你有没有想过&#xff0c;只需要一张照片和一段音频&#xff0c;就能让虚拟人物“活”起来&#xff0c;开口说话、表情自然、动作流畅&#xff1f;这不…

作者头像 李华
网站建设 2026/2/28 4:15:23

代码生成实测:Qwen3-0.6B在编程题上的表现如何

代码生成实测&#xff1a;Qwen3-0.6B在编程题上的表现如何 1. 引言&#xff1a;小模型也能写好代码&#xff1f; 你有没有想过&#xff0c;一个只有6亿参数的AI模型&#xff0c;能不能帮你写出一段能跑通的Python函数&#xff1f;这听起来有点像“用自行车拉火车”——体量太…

作者头像 李华