亲自动手搭建:从创建到启用全程实录演示

亲自动手搭建:从创建到启用全程实录演示

你是否遇到过这样的问题:写好了一个Python脚本,希望它在系统启动时自动运行,但每次重启后都得手动执行?或者试了几次rc.local却始终没看到预期效果,日志里空空如也,服务状态显示“inactive”?别急——这不是你的操作错了,而是Ubuntu 18.04及后续版本对开机自启机制做了根本性调整。老办法失效了,但新方法其实更可靠、更清晰,只是少有人把每一步的真实反馈和常见卡点讲透。

本文不讲抽象原理,不堆术语,只带你亲手走完从零创建到验证生效的完整闭环。每一步都基于真实终端操作截图逻辑还原,所有命令可直接复制粘贴,所有报错都有对应解法。你会看到:

  • 为什么/etc/rc.local默认不工作;
  • 怎样让systemd真正“认出”这个传统脚本入口;
  • 如何安全地把业务逻辑(比如Python程序)嵌入启动流程;
  • 出现失败时,第一眼该看哪条日志、查哪个状态、改哪行代码。

准备好了吗?我们这就开始——不是模拟,是实录。

1. 理解变化:为什么老方法在Ubuntu 18.04+上失效了

在Ubuntu 14.04时代,编辑/etc/rc.local几乎是开机自启的“万能钥匙”。但到了18.04,系统全面转向systemd管理服务,而rc.local本身只是一个遗留兼容接口——它不再被默认启用,也不再由init自动加载。简单说:文件还在,但没人读它。

这带来两个关键事实:

  • 即使你把命令写进/etc/rc.local,只要没有配套的systemd服务单元(.service文件),它就永远不会被执行;
  • rc.local的执行权限、退出码、路径环境,全部受systemd服务定义约束,不再是过去那种“扔进去就跑”的宽松模式。

所以,真正的起点不是写脚本,而是先让systemd认识并信任rc.local这个入口。下面这一步,决定了整条链路能否打通。

2. 创建rc-local.service:给rc.local装上systemd“驱动”

这一步是整个方案的基石。我们需要告诉systemd:“请把/etc/rc.local当作一个合法服务来管理,并在多用户模式下启动它。”

2.1 创建服务定义文件

打开终端,执行:

sudo vim /etc/systemd/system/rc-local.service

将以下内容完整粘贴进去(注意:不要漏掉任何一行,尤其是空行和缩进):

[Unit] Description=/etc/rc.local Compatibility ConditionPathExists=/etc/rc.local [Service] Type=forking ExecStart=/etc/rc.local start TimeoutSec=0 StandardOutput=tty RemainAfterExit=yes SysVStartPriority=99 [Install] WantedBy=multi-user.target

关键点说明

  • ConditionPathExists=/etc/rc.local:确保只有当/etc/rc.local文件存在时,该服务才被允许启用。这是防止配置错误导致系统异常的保险机制;
  • Type=forking:因为rc.local传统上会派生子进程,必须声明为forking类型,否则systemd会误判服务已退出;
  • RemainAfterExit=yes:告诉systemd:“即使rc.local脚本执行完了,也请继续保持服务为‘激活’状态”,这样才能让后续依赖它的服务正常启动;
  • WantedBy=multi-user.target:明确指定该服务应在标准多用户运行级别(即图形界面或纯命令行登录环境)下启动。

保存并退出vim(:wq)。

2.2 验证服务文件语法

在启用前,先检查语法是否正确,避免因格式错误导致服务无法加载:

sudo systemctl daemon-reload sudo systemctl cat rc-local.service

如果输出显示完整的service内容,说明文件已成功注册;若提示“No such file or directory”,请返回上一步检查路径和文件名是否完全一致(注意大小写和后缀)。

3. 编写rc.local:不只是占位,而是可靠启动索引

rc.local现在不是终点,而是起点——它应该是一个轻量、稳定、职责单一的“启动索引”,负责调用你真正的业务脚本。这样既保持传统习惯,又便于后期维护。

3.1 创建并编辑rc.local文件

sudo vim /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. echo "rc.local 已触发,当前时间:$(date)" > /usr/local/rc-local-triggered.log # 此处添加你的实际启动命令,例如: # /home/lbw/test.sh exit 0

为什么这样写?

  • #!/bin/sh -e:强制使用POSIX shell,并在任意命令失败时立即退出(避免静默错误);
  • echo行:提供最直接的执行证据——只要/usr/local/rc-local-triggered.log生成且有时间戳,就证明rc.local已被systemd成功调用;
  • exit 0:必须显式返回0,否则systemd会认为脚本执行失败,进而标记服务为failed

3.2 设置执行权限

sudo chmod +x /etc/rc.local

这步不可省略。systemd要求rc.local必须有可执行权限,否则拒绝启动。

4. 启用并启动服务:让systemd真正接管

现在,rc-local.service定义好了,rc.local也准备就绪。接下来,让systemd把它纳入管理。

4.1 启用服务(开机自启)

sudo systemctl enable rc-local.service

执行后,你会看到类似输出:
Created symlink /etc/systemd/system/multi-user.target.wants/rc-local.service → /etc/systemd/system/rc-local.service.
这表示systemd已在启动目标中建立了软链接,下次开机时会自动加载此服务。

4.2 立即启动服务(无需重启)

sudo systemctl start rc-local.service

4.3 检查服务状态(关键验证步骤)

sudo systemctl status rc-local.service

理想状态应显示:

● rc-local.service - /etc/rc.local Compatibility Loaded: loaded (/etc/systemd/system/rc-local.service; enabled; vendor preset: enabled) Active: active (exited) since ...; X seconds ago Docs: man:systemd-rc-local-generator(8)

重点关注两点:

  • Loaded行中的enabled:确认已设置为开机启动;
  • Active行中的active (exited):表明服务已成功执行完毕(注意不是running,因为rc.local是短时任务)。

如果看到failedinactive
立即执行:

sudo journalctl -u rc-local.service -n 20 --no-pager

查看最近20行日志。90%的问题都能在这里定位——比如路径不存在、权限不足、脚本语法错误等。

4.4 验证rc.local是否真被调用

检查我们之前写的日志文件:

cat /usr/local/rc-local-triggered.log

你应该看到类似:
rc.local 已触发,当前时间:Wed 12 Jun 2024 10:23:45 CST
这证明systemd已成功驱动rc.local执行,整个基础链路已通。

5. 部署你的业务脚本:以Python为例的安全集成

现在,rc.local已可靠运行。下一步,把你的实际任务(比如一个Python程序)接入进来。这里以test.sh调用ce.py为例,重点解决三个实战痛点:路径问题、环境变量、中文编码。

5.1 创建业务脚本test.sh

sudo vim /home/lbw/test.sh

内容如下(注意:路径、用户、解释器需按你实际情况修改):

#!/bin/bash # 切换到脚本所在目录,避免相对路径错误 cd /home/lbw || exit 1 # 显式指定Python解释器路径(推荐用绝对路径,避免PATH差异) /usr/bin/python3 ce.py # 记录执行结果,便于排查 echo "test.sh 执行完成,时间:$(date)" >> /usr/local/test-sh-ran.log exit 0

为什么强调/usr/bin/python3
在systemd服务环境下,PATH环境变量与用户终端不同,默认可能不包含/usr/local/bin或你的conda环境。硬编码绝对路径是最稳妥的做法。

5.2 创建Python程序ce.py

sudo vim /home/lbw/ce.py

内容(简洁版,无中文字符):

#!/usr/bin/env python3 import os # 确保写入路径存在且可写 log_path = "/usr/local/sb.txt" try: with open(log_path, "w") as f: f.write("SB from ce.py at " + os.popen("date").read().strip()) print(f"成功写入 {log_path}") except Exception as e: print(f"写入失败:{e}")

关键防护措施:

  • 使用#!/usr/bin/env python3声明解释器,同时在脚本内用/usr/bin/python3调用,双重保障;
  • 添加try/except捕获IO异常,并打印具体错误,避免静默失败;
  • os.popen("date")替代datetime.now(),减少模块依赖,提升兼容性。

5.3 赋予执行权限并更新rc.local

sudo chmod +x /home/lbw/test.sh

然后编辑/etc/rc.local,取消注释并修改调用行:

sudo vim /etc/rc.local

将其中的:
# /home/lbw/test.sh
改为:
/home/lbw/test.sh

保存退出。

5.4 重新加载并测试

sudo systemctl daemon-reload sudo systemctl restart rc-local.service sudo systemctl status rc-local.service

再次检查日志:

cat /usr/local/sb.txt cat /usr/local/test-sh-ran.log

如果看到SB from ce.py at ...test.sh 执行完成,恭喜,你的业务逻辑已成功融入开机流程。

6. 常见问题与排障清单:比文档更实用的实战经验

即使严格按步骤操作,仍可能遇到意外。以下是根据真实部署反馈整理的高频问题及速查方案:

6.1 服务状态显示“failed”,journalctl日志为空

原因rc.local文件权限不对,或exit语句缺失/错误。
检查命令

ls -l /etc/rc.local # 应显示 -rwxr-xr-x,即包含x(执行)权限 head -n 5 /etc/rc.local | grep exit # 确保最后一行是 exit 0

6.2 test.sh能手动运行,但开机时不执行

原因test.sh中调用的Python脚本含中文字符,或未指定-u参数导致缓冲区阻塞。
解决方案

  • 将Python脚本中的中文字符串替换为英文,或在shebang后加-u#!/usr/bin/env python3 -u
  • test.sh中添加环境变量:export PYTHONIOENCODING=utf-8

6.3 写入文件失败,提示“Permission denied”

原因/usr/local/目录默认仅root可写,而test.sh以root身份运行,但Python脚本内open()可能因umask限制失败。
安全写法

with open("/usr/local/sb.txt", "w", encoding="utf-8") as f: f.write(...)

并确保/usr/local/目录权限为drwxr-xr-x(755)。

6.4 修改rc.local后服务不生效

必须执行的三步

  1. sudo chmod +x /etc/rc.local(重设权限);
  2. sudo systemctl daemon-reload(重载服务定义);
  3. sudo systemctl restart rc-local.service(重启服务);
    缺一不可。

7. 总结:一条可复用、可验证、可扩展的启动链路

回看整个过程,我们构建的不是一个临时补丁,而是一条清晰、可控、易维护的启动链路:

  • 底层驱动rc-local.service—— systemd原生服务,稳定可靠;
  • 统一入口/etc/rc.local—— 职责单一,只做调度,不掺杂业务逻辑;
  • 业务载体/home/lbw/test.sh—— 可独立测试、版本管理、权限隔离;
  • 最终执行ce.py—— 专注核心功能,错误处理完备。

这条链路的价值在于:
可验证:每个环节都有明确输出(日志文件、服务状态、终端反馈);
可复用:只需替换test.sh内容,即可适配Shell、Python、Node.js等任意语言脚本;
可扩展:未来可轻松增加多个.sh脚本,通过rc.local顺序调用,形成启动任务队列。

现在,你可以放心重启系统:

sudo reboot

等待登录后,第一时间检查:

cat /usr/local/sb.txt sudo systemctl status rc-local.service

如果一切如常,那么恭喜你——不仅完成了开机自启的配置,更掌握了一套在现代Linux系统中安全、可靠、可追溯的自动化部署方法论。


获取更多AI镜像

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1219612.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实战案例:使用SystemVerilog构建AHB验证组件

以下是对您提供的博文内容进行 深度润色与结构重构后的专业级技术文章 。我以一位深耕验证领域十年、主导过多个SoC项目UVM平台建设的资深验证工程师视角,彻底摒弃模板化表达和AI腔调,用真实工程语言重写全文——不堆砌术语,不空谈概念&…

YOLOv12官版镜像实测报告,精度与速度表现如何?

YOLOv12官版镜像实测报告,精度与速度表现如何? YOLOv12不是迭代编号的简单延续,而是一次范式跃迁——它彻底告别了卷积主干的路径依赖,将注意力机制推向前台中央。当行业还在为RT-DETR的推理延迟皱眉时,YOLOv12已用1.…

UNet人脸融合目标图像选择技巧

UNet人脸融合目标图像选择技巧 在人脸融合实践中,很多人把注意力集中在源图像(提供人脸的那张)上,却忽略了目标图像——也就是被融合的背景图——对最终效果的决定性影响。事实上,目标图像的选择直接决定了融合是否自…

告别复杂部署!科哥的人像卡通化镜像开箱即用

告别复杂部署!科哥的人像卡通化镜像开箱即用 你是否试过为一张照片调半天滤镜,却始终达不到想要的二次元效果?是否在GitHub上翻遍项目README,被CUDA版本、PyTorch兼容性、模型权重下载路径绕得头晕眼花?是否刚配好环境…

如何在本地快速运行YOLOv12?这个镜像太强了

如何在本地快速运行YOLOv12?这个镜像太强了 你有没有试过:刚下载完一个目标检测镜像,双击启动,几秒后就看到终端里跳出一行绿色文字——model loaded successfully,接着一张公交图片自动弹出窗口,上面密密…

用Z-Image-Turbo做AI绘画,效果惊艳又省显存

用Z-Image-Turbo做AI绘画,效果惊艳又省显存 你有没有试过点开一个AI绘画工具,刚输入“一只在咖啡馆看书的温柔女孩”,等了半分钟,进度条卡在92%,显存占用飙到98%,最后弹出一行红字:“CUDA out …

用Qwen-Image-Layered重构老照片,细节还原超预期

用Qwen-Image-Layered重构老照片,细节还原超预期 老照片泛黄、划痕密布、人物模糊——这些不是怀旧滤镜,而是真实的时间伤痕。你是否试过用传统修图工具修复一张1980年代的家庭合影?放大后发丝边缘锯齿、背景纹理失真、肤色调整牵一发而动全…

一键安装单节点 Zookeeper 3.8.5(附完整 Bash 脚本)

适用环境:CentOS / Ubuntu / 其他 Linux 发行版 用途:开发测试、学习 Zookeeper 基础使用 ✅ 前提条件 以 root 用户运行(或具有 sudo 权限)已安装完整 JDK(非 JRE),并正确配置 JAVA_HOME 环境…

远程教学支持:Multisim安装离线配置方法

以下是对您提供的博文《远程教学支持:Multisim离线安装与仿真环境预配置技术分析》的 深度润色与专业重构版本 。本次优化严格遵循您的全部要求: ✅ 彻底去除AI痕迹,语言自然、专业、有“人味”——像一位在高校电类实验室摸爬滚打十年的工…

FPGA中低功耗触发器设计:电源管理实践案例

以下是对您提供的技术博文《FPGA中低功耗触发器设计:电源管理实践案例》的 深度润色与重构版本 。本次优化严格遵循您的全部要求: ✅ 彻底去除AI痕迹,语言自然、专业、有“人味”——像一位在工业FPGA一线摸爬滚打十年的架构师&#xff0c…

FSMN-VAD实战体验:上传音频秒出语音时间段

FSMN-VAD实战体验:上传音频秒出语音时间段 你是否遇到过这样的问题:一段10分钟的会议录音里,真正说话的时间可能只有3分钟,其余全是静音、咳嗽、翻纸声甚至空调噪音?手动听写剪辑耗时费力,用传统工具又容易…

数字人创业新机会,Live Avatar商业应用场景解析

数字人创业新机会,Live Avatar商业应用场景解析 1. 为什么Live Avatar值得创业者关注 数字人技术正从实验室走向真实商业场景,但多数方案要么效果粗糙,要么成本高得离谱。Live Avatar的出现,像在拥挤的赛道里突然打开一扇新门—…

Redis - hash list (常用命令/内部编码/应用场景) - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

朝阳狗狗训练哪家好?朝阳狗狗训练专业正规基地名单(2026年新版)

对于朝阳的养宠人来说,给毛孩子找一家靠谱的狗狗训练机构,既要兼顾专业性与正规性,也要考量场地条件和服务品质。狗狗的不良行为矫正、服从训练,以及寄养期间的生活照料,每一项都牵动着主人的心。优质的机构能让毛…

利用51单片机实现蜂鸣器唱歌的简易音乐玩具

以下是对您提供的博文进行 深度润色与专业重构后的版本 。全文已彻底去除AI生成痕迹,采用真实嵌入式工程师口吻写作,逻辑更紧凑、语言更凝练、技术细节更扎实,并强化了教学性、工程实践性和可复现性。所有结构化标题均被自然段落过渡替代&a…

基于PetaLinux的GPIO驱动设计与实现

以下是对您提供的博文《基于PetaLinux的GPIO驱动设计与实现:从设备树到用户态的全链路工程实践》进行 深度润色与重构后的技术文章 。本次优化严格遵循您的全部要求: ✅ 彻底去除AI痕迹,语言自然、专业、有“人味”,像一位资深…

AI绘画提速神器!Z-Image-Turbo 8步出图实测分享

AI绘画提速神器!Z-Image-Turbo 8步出图实测分享 你有没有过这样的体验:输入一段提示词,盯着进度条等了20秒,结果生成的图细节糊、手长三只、文字错乱,还得重来?或者想快速给运营同事出5版海报草稿&#xf…

工业质检新方案:用YOLOE镜像打造实时检测系统

工业质检新方案:用YOLOE镜像打造实时检测系统 在制造业智能化升级的深水区,产线质检正面临一场静默却深刻的变革。过去依赖人工目检的环节,正被一种更“懂语言”的AI视觉系统悄然替代——它不再需要提前定义所有缺陷类型,也不必为…

如何用AI高效抠图?科哥开发的WebUI工具给出了答案

如何用AI高效抠图?科哥开发的WebUI工具给出了答案 你有没有过这样的经历:为了给一张产品图换背景,花半小时在PS里反复调整魔棒和钢笔工具;为了做一组社交媒体头像,一张张手动擦除背景边缘;或者面对几十张模…

金融客服升级:Live Avatar实现AI数字人答疑

金融客服升级:Live Avatar实现AI数字人答疑 在银行网点、证券APP和保险热线中,客户常常需要反复描述问题、等待转接、重复确认信息——传统语音客服的机械应答与文字客服的响应延迟,正成为金融服务体验的瓶颈。当用户问“我的理财收益为什么…