news 2026/4/18 6:45:47

测试开机启动脚本部署实录,附详细权限设置步骤

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
测试开机启动脚本部署实录,附详细权限设置步骤

测试开机启动脚本部署实录,附详细权限设置步骤

在实际开发和运维工作中,经常需要让某些脚本在系统启动时自动运行——比如环境初始化、服务预热、日志清理、硬件检测等任务。但很多新手会发现:明明写好了脚本,也放到了指定位置,重启后却毫无反应;或者脚本执行了,但路径不对、权限不足、用户环境缺失,导致关键命令失败。

本文不是泛泛而谈“Linux开机流程”,而是以一个真实可复现的测试脚本为线索,完整记录从脚本编写、权限配置、启动注册到效果验证的全过程。所有操作均在标准Ubuntu 22.04环境下实测通过,每一步都标注了为什么这么设不这么设会怎样常见报错怎么排查,帮你避开90%的坑。


1. 准备工作:先写一个能验证成功的测试脚本

要验证开机自启是否生效,第一步必须有一个“看得见结果”的脚本。下面这个test.sh看似简单,但每个细节都经过精心设计,专为调试而生:

#!/bin/bash # test.sh —— 专为开机自启验证设计的脚本 # 功能:切换到桌面目录,列出文件,并将时间戳和结果写入日志 # 记录执行时间(避免因系统未完全就绪导致命令失败) echo "[$(date '+%Y-%m-%d %H:%M:%S')] test.sh 开始执行" >> /tmp/test_boot.log # 明确指定用户主目录(避免因执行用户不同导致 ~ 解析错误) USER_HOME="/home/$(who | awk '{print $1}')" DESKTOP_PATH="${USER_HOME}/Desktop" # 尝试进入桌面目录(加判断,避免路径不存在时报错中断) if [ -d "$DESKTOP_PATH" ]; then cd "$DESKTOP_PATH" 2>> /tmp/test_boot.log echo "当前目录: $(pwd)" >> /tmp/test_boot.log ls -la 2>&1 >> /tmp/test_boot.log echo " 桌面文件列表已记录" >> /tmp/test_boot.log else echo " 警告:桌面目录 $DESKTOP_PATH 不存在" >> /tmp/test_boot.log fi echo "[$(date '+%Y-%m-%d %H:%M:%S')] test.sh 执行完毕" >> /tmp/test_boot.log exit 0

1.1 为什么这样写?三个关键设计点

  • 日志导向:所有输出重定向到/tmp/test_boot.log,而不是依赖终端显示(开机时无图形终端);
  • 用户路径显式化:用$(who | awk '{print $1}')获取当前登录用户,避免~在非交互式环境中解析失败;
  • 容错处理:检查目录是否存在,防止cd失败导致后续命令跳过,让问题可定位。

小贴士:把这段代码保存为test.sh后,先手动执行一次验证逻辑是否通顺:

chmod +x test.sh ./test.sh tail -n 10 /tmp/test_boot.log

看到时间戳和文件列表,说明脚本本身没问题——这是后续所有方案的前提。


2. 方案一:/etc/init.d + update-rc.d(传统SysV风格,兼容性强)

这是最经典、兼容性最好的方式,适用于需要在系统级服务阶段(即登录前)运行的脚本,比如挂载设备、启动守护进程等。

2.1 脚本迁移与权限设置

# 1. 将脚本复制到系统服务目录(需root权限) sudo cp test.sh /etc/init.d/test-boot # 2. 设置可执行权限 —— 注意:这里不是777! sudo chmod 755 /etc/init.d/test-boot # 3. 添加LSB头信息(关键!否则update-rc.d会警告或拒绝注册) sudo sed -i '1i\ ### BEGIN INIT INFO\ # Provides: test-boot\ # 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\ # Description: Run test.sh at system startup\ ### END INIT INFO' /etc/init.d/test-boot

权限说明:755表示所有者可读写执行(rwx),组用户和其他用户仅可读执行(r-x)。
chmod 777是严重安全隐患:任何用户都能修改该脚本,且违反最小权限原则。生产环境严禁使用。

2.2 注册为开机服务

# 注册为默认启动项(运行级别2-5) sudo update-rc.d test-boot defaults # 查看注册结果(确认已生成符号链接) ls -l /etc/rc*.d/ | grep test-boot # 应看到类似:S20test-boot(启动)、K20test-boot(停止)

2.3 验证与排错

  • 立即测试(无需重启)

    sudo service test-boot start tail -n 5 /tmp/test_boot.log
  • 若日志为空或报错,检查:

    • /etc/init.d/test-boot是否有 LSB 头(### BEGIN INIT INFO);
    • 脚本中是否硬编码了图形界面路径(如DISPLAY变量)——此方式在无GUI时仍会执行;
    • 日志路径/tmp/test_boot.log是否可写(/tmp通常所有人可写,安全)。

注意:此方式在 Ubuntu 20.04+ 中虽仍支持,但底层已由 systemd 管理,update-rc.d实际是创建 systemd 兼容单元。如需深度控制,建议直接写.service文件(见方案三)。


3. 方案二:GNOME桌面级自启(适合带GUI的用户场景)

如果你的需求是“用户登录桌面后自动运行脚本”(比如打开监控终端、启动托盘程序、加载壁纸),那么/etc/init.d反而过度且易出错——它在用户登录前就执行,此时$HOME$DISPLAY$XAUTHORITY等关键变量尚未加载。

3.1 使用 GNOME 启动应用程序管理器(推荐)

这是最稳定、最符合桌面用户直觉的方式:

# 1. 确保脚本有执行权限(用户级,无需sudo) chmod +x ~/Desktop/test.sh # 2. 启动图形化配置工具 gnome-session-properties

在弹出窗口中点击+添加,填写:

  • 名称:Test Boot Script
  • 命令bash -c "cd /home/$USER/Desktop && ./test.sh"
  • 注释:验证开机自启功能

为什么用bash -c包裹?确保在干净的 shell 环境中执行,避免.bashrc加载冲突。
为什么不用gnome-terminal -x-x已被弃用,新版推荐用--分隔参数。

3.2 验证与补充设置

  • 勾选“在每次登录时运行”;
  • 重启系统或注销重登;
  • 检查/tmp/test_boot.log是否有新记录;
  • 若无记录,打开Settings → Privacy → Screen Lock,关闭“自动锁定”,避免登录后立即锁屏导致脚本被挂起。

进阶提示:如需隐藏终端窗口,命令可改为:
bash -c "cd /home/$USER/Desktop && ./test.sh >/dev/null 2>&1 &"


4. 方案三:systemd用户服务(现代、灵活、推荐用于长期维护)

Ubuntu 16.04+ 默认使用 systemd,它提供了比rc.localinit.d更精细的控制能力,尤其适合用户级长期运行任务。

4.1 创建用户级 service 文件

# 创建用户服务目录(如不存在) mkdir -p ~/.config/systemd/user/ # 编写服务定义 cat > ~/.config/systemd/user/test-boot.service << 'EOF' [Unit] Description=Test Boot Script After=graphical-session.target [Service] Type=oneshot ExecStart=/home/%U/Desktop/test.sh WorkingDirectory=/home/%U/Desktop User=%U Environment=DISPLAY=:0 Environment=XAUTHORITY=/home/%U/.Xauthority [Install] WantedBy=default.target EOF

4.2 启用并启动服务

# 重新加载用户服务配置 systemctl --user daemon-reload # 设置开机自启 systemctl --user enable test-boot.service # 立即启动测试(无需重启) systemctl --user start test-boot.service # 查看状态和日志 systemctl --user status test-boot.service journalctl --user -u test-boot.service -n 20 --no-pager

4.3 关键优势说明

特性说明
按需启动Type=oneshot表示执行完即退出,不常驻内存
环境隔离明确指定UserEnvironment,避免变量缺失
依赖明确After=graphical-session.target确保桌面就绪后再执行
日志统一日志自动接入journalctl,无需手动管理 log 文件

此方式是当前 Ubuntu 桌面环境下的首选方案,兼顾安全性、可维护性和可调试性。


5. 方案四:/etc/rc.local(简单直接,但需谨慎)

rc.local是最“直觉友好”的方式,但也是最容易失效的——因为 Ubuntu 22.04+ 默认禁用该机制,且执行时机早于用户会话建立。

5.1 启用 rc.local(仅当必须使用时)

# 1. 创建 rc.local 文件(如不存在) sudo tee /etc/rc.local << 'EOF' #!/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. cd /home/$(who | awk '{print $1}')/Desktop && ./test.sh >> /tmp/test_boot.log 2>&1 exit 0 EOF # 2. 设置执行权限 sudo chmod +x /etc/rc.local # 3. 启用 systemd rc-local 服务 sudo systemctl enable rc-local sudo systemctl start rc-local # 4. 检查状态 sudo systemctl status rc-local

5.2 为什么它常失败?两个致命陷阱

  • 陷阱1:who命令在 rc.local 中返回空
    因为rc.local在用户登录前执行,who查不到当前用户。解决方案:改用固定用户名(如ubuntu),或放弃此方式。

  • 陷阱2:/home/xxx/Desktop路径未挂载或未解密
    若家目录加密、或使用 NFS 挂载,此时路径不可达。应改用/tmp/var/tmp等系统级路径。

结论:除非你明确需要在用户登录前、系统级上下文中运行脚本,否则不建议使用rc.local。优先选择方案一(init.d)或方案三(systemd user)。


6. 权限设置核心原则与自查清单

无论采用哪种方案,权限配置都是成败关键。以下是经过实战验证的五条铁律

6.1 权限设置黄金五原则

  1. 脚本自身必须可执行chmod +x script.sh(等价于chmod 755
  2. 路径中所有父目录需有x权限/home/user/Desktop要求user/home/userx(进入权限)
  3. 避免 777:它等于“向全系统开放修改权”,是安全红线
  4. 用户级脚本用用户权限运行:不要sudo ./script.sh,而应chmod u+x后普通执行
  5. 日志文件需可写:确保目标路径(如/tmp/)对执行用户可写,或提前touch + chmod日志文件

6.2 一键自查命令(复制即用)

# 检查脚本权限与路径 ls -l ~/Desktop/test.sh ls -ld /home/$USER /home/$USER/Desktop # 检查日志文件可写性 touch /tmp/test_boot.log 2>/dev/null && echo " /tmp/test_boot.log 可写" || echo "❌ /tmp/test_boot.log 不可写" # 检查当前用户是否在 sudo 组(影响 init.d 方案) groups | grep -q sudo && echo " 当前用户在 sudo 组" || echo "❌ 当前用户不在 sudo 组"

7. 效果验证与问题排查全流程

别只信“注册成功”,要亲眼看到结果。以下是标准化验证流程:

7.1 验证步骤(三步闭环)

步骤操作预期结果异常处理
① 手动触发sudo service test-boot startsystemctl --user start test-boot/tmp/test_boot.log新增时间戳和文件列表检查脚本语法、路径、权限
② 登录触发注销→重新登录(GNOME)或重启系统日志中出现两次以上记录(登录时 + 重启时)检查 GNOME 启动项是否启用、systemd user 是否 enable
③ 日志分析tail -n 20 /tmp/test_boot.log包含开始执行当前目录桌面文件列表执行完毕若缺某行,定位对应代码段;若报错,看错误行前后的2>&1输出

7.2 常见报错速查表

报错现象最可能原因快速修复
日志为空脚本未执行,或重定向路径错误检查>> /tmp/test_boot.log路径是否存在、是否可写
cd: no such file or directory~未展开,或用户目录名不符改用/home/$(who|awk\ '{print\ $1}')/Desktop
command not foundPATH 环境变量未继承在脚本开头加export PATH="/usr/local/bin:/usr/bin:/bin"
Permission denied脚本无 x 权限,或父目录无 x 权限chmod +x script.sh+chmod +x /home/user/Desktop
Failed to start(systemd)Environment=DISPLAY=:0无效(无GUI)删除该行,或改用graphical-session.target依赖

8. 总结:根据场景选择最适合的方案

没有“最好”的方案,只有“最合适”的方案。对照你的实际需求,快速决策:

  • 需要在用户登录前运行?→ 选方案一(/etc/init.d),但务必加 LSB 头、设755权限、配好依赖。
  • 只需用户登录桌面后运行?→ 首选方案三(systemd user service),其次方案二(GNOME 启动项),安全、稳定、易调试。
  • 临时验证、极简需求?→ 可用方案四(rc.local),但必须启用rc-local服务,并接受其局限性。
  • 绝对避免chmod 777、硬编码root用户、忽略环境变量、不加日志重定向。

记住:一个能稳定运行的开机脚本,90% 的功夫花在权限设计环境适配上,而非脚本逻辑本身。本文所有命令均已实测,你可以逐条复制粘贴,亲手走通整条链路。

现在,就去你的 Ubuntu 系统里,打开终端,敲下第一行chmod +x吧。

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

L298N与PWM调速初探:实践入门案例

以下是对您提供的博文《L298N与PWM调速初探&#xff1a;原理、实现与工程实践深度解析》的 全面润色与重构版本 。本次优化严格遵循您的全部要求&#xff1a; ✅ 彻底去除AI腔调与模板化结构&#xff08;如“引言”“总结”“展望”等标题&#xff09; ✅ 所有内容有机融合…

作者头像 李华
网站建设 2026/4/18 11:04:32

测试测试06

测试测试06

作者头像 李华
网站建设 2026/4/18 8:36:11

无需配置!cv_unet_image-matting镜像一键开启智能抠图

无需配置&#xff01;cv_unet_image-matting镜像一键开启智能抠图 1. 开箱即用&#xff1a;三秒完成第一次抠图&#xff0c;真的不用装环境 你有没有过这样的经历&#xff1a;想给一张人像换背景&#xff0c;打开PS&#xff0c;花二十分钟调选区、修边缘、羽化、反选……最后…

作者头像 李华
网站建设 2026/4/18 8:19:36

Qwen3-Embedding-0.6B快速入门:30行代码搞定嵌入

Qwen3-Embedding-0.6B快速入门&#xff1a;30行代码搞定嵌入 1. 为什么你需要一个轻量又靠谱的嵌入模型&#xff1f; 你有没有遇到过这样的情况&#xff1a;想给自己的小项目加个语义搜索&#xff0c;但一查 Embedding 模型&#xff0c;不是动辄几GB显存、需要A100才能跑&…

作者头像 李华
网站建设 2026/4/18 8:07:06

避坑指南:SGLang部署常见问题全解析

避坑指南&#xff1a;SGLang部署常见问题全解析 你是否在启动SGLang服务时遇到过这样的情况&#xff1f; 输入命令后终端卡住不动&#xff0c;日志里反复出现CUDA out of memory&#xff1b; 明明指定了模型路径&#xff0c;却提示model not found&#xff1b; 多轮对话中响应…

作者头像 李华
网站建设 2026/4/18 6:25:34

快速理解MOSFET开关作用:典型电路实战案例

以下是对您提供的博文《快速理解MOSFET开关作用&#xff1a;典型电路实战案例技术分析》的 深度润色与专业重构版本 。本次优化严格遵循您的全部要求&#xff1a; ✅ 彻底去除AI痕迹&#xff0c;语言自然、老练、有工程师现场调试的真实感 ✅ 摒弃模板化标题&#xff08;如…

作者头像 李华