Ubuntu开机启动不再难,一文教会你全部步骤
1. 引言
1.1 业务场景描述
在实际的服务器运维和嵌入式设备管理中,经常需要让某些脚本或程序在系统启动时自动运行。例如:启动监控服务、初始化环境变量、运行Python数据采集脚本等。Ubuntu 18.04 及之后版本基于 systemd 架构,传统的/etc/rc.local开机启动方式默认已被弃用,这让许多习惯于旧版 Ubuntu 的开发者感到困扰。
1.2 痛点分析
Ubuntu 14.04 时代可以通过简单编辑/etc/rc.local文件实现开机自启,但从 16.04 开始逐步过渡到 systemd 后,该文件不再生效。直接修改 systemd 配置又显得复杂,学习成本高。如何在保持简洁性的同时兼容传统习惯,成为一大痛点。
1.3 方案预告
本文将详细介绍如何在 Ubuntu 18.04+ 系统中重新启用/etc/rc.local,并通过它来执行任意自定义脚本(如 Shell 脚本、Python 程序等),实现灵活、稳定、可调试的开机启动机制。整个过程无需深入理解 systemd 复杂语法,适合初级到中级用户快速上手。
2. 技术方案选型与原理说明
2.1 为什么不能直接使用 rc.local?
Ubuntu 从 16.04 起全面采用systemd作为初始化系统(init system),而rc.local是 System V init 时代的遗留机制。虽然系统仍保留了/etc/rc.local文件路径,但默认没有对应的 service 单元去调用它,因此不会被执行。
2.2 解决思路:创建兼容性服务单元
我们通过手动创建一个名为rc-local.service的 systemd 服务单元文件,告诉系统:“当进入多用户模式时,请执行/etc/rc.local start”。这样既复用了熟悉的rc.local接口,又符合 modern Linux 的启动规范。
2.3 核心优势
- ✅ 兼容性强:适用于 Ubuntu 18.04、20.04、22.04 等主流 LTS 版本
- ✅ 操作简单:只需配置一次 service 文件,后续只需修改
rc.local - ✅ 易于调试:可通过
systemctl status查看执行状态和错误日志 - ✅ 安全可控:遵循 systemd 权限模型,避免权限越界问题
3. 实现步骤详解
3.1 创建 rc-local.service 文件
首先,我们需要为 systemd 添加一个服务单元,使其识别并加载rc.local。
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存在时才启动此服务Type=forking:表示服务会 fork 子进程后退出主进程(符合 rc.local 行为)RemainAfterExit=yes:即使主进程退出,也认为服务仍在运行WantedBy=multi-user.target:在多用户文本界面启动时激活
3.2 创建并配置 /etc/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 "看到这行字,说明添加自启动脚本成功。" > /usr/local/test.log exit 0注意:最后一行必须是
exit 0,否则 systemd 会认为脚本执行失败。
3.3 设置权限并启用服务
赋予rc.local可执行权限:
sudo chmod +x /etc/rc.local启用服务(开机自动启动):
sudo systemctl enable rc-local输出示例:
Created symlink /etc/systemd/system/multi-user.target.wants/rc-local.service → /etc/systemd/system/rc-local.service.3.4 启动服务并检查状态
立即启动服务进行测试:
sudo systemctl start rc-local.service查看服务状态:
sudo systemctl status rc-local.service正常输出应包含:
active (exited) since ...如果出现failed,请使用以下命令排查日志:
journalctl -u rc-local.service --since "5 minutes ago"3.5 验证日志输出
重启系统或等待服务执行完成后,检查日志文件是否生成:
cat /usr/local/test.log预期输出:
看到这行字,说明添加自启动脚本成功。若能看到该内容,则表明rc.local已成功运行。
4. 扩展应用:启动自定义脚本
4.1 设计思路
建议不要将所有逻辑写入/etc/rc.local,而是将其作为“启动入口”,用于调用外部脚本。这样更便于维护和权限隔离。
4.2 创建自定义 Shell 脚本
创建测试脚本:
sudo vim /opt/test.sh内容如下:
#!/bin/bash cd /home/ubuntu/ python3 /home/ubuntu/ce.py exit 0赋予执行权限:
sudo chmod +x /opt/test.sh4.3 创建 Python 测试程序
创建 Python 脚本用于验证执行:
vim ~/ce.py内容如下:
with open("/home/ubuntu/sb.txt", "w") as f: f.write("SB")4.4 修改 rc.local 调用外部脚本
编辑/etc/rc.local,替换原有echo行:
sudo vim /etc/rc.local修改为:
#!/bin/sh -e # 调用外部脚本 /opt/test.sh exit 0保存后重新启动服务:
sudo systemctl restart rc-local.service检查是否生成sb.txt:
cat /home/ubuntu/sb.txt预期输出:
SB5. 常见问题与优化建议
5.1 常见问题及解决方案
| 问题现象 | 原因分析 | 解决方法 |
|---|---|---|
rc-local.service failed | /etc/rc.local缺少执行权限 | 运行sudo chmod +x /etc/rc.local |
| 日志文件未生成 | 脚本路径错误或目录不存在 | 检查路径是否存在,建议使用绝对路径 |
| Python 脚本报错编码异常 | 文件包含中文字符或编码不匹配 | 使用 UTF-8 编码保存,避免中文注释 |
No such file or directory | 调用的脚本无执行权限或解释器路径错误 | 确保脚本有+x权限,并指定完整解释器路径(如/usr/bin/python3) |
5.2 最佳实践建议
- 统一使用绝对路径
所有脚本、文件、命令都应使用绝对路径,避免因工作目录不同导致失败。
示例:bash /usr/bin/python3 /home/user/app.py
- 添加日志记录便于调试
在关键步骤写入时间戳日志,方便定位问题。
bash echo "$(date): 自定义脚本开始执行" >> /var/log/boot.log
- 避免阻塞启动流程
若脚本运行时间较长,建议后台运行或加&放入后台:
bash /opt/long-running-script.sh &
- 定期清理临时日志
可配合logrotate或定时任务清理/var/log/boot.log等启动日志。
6. 总结
6.1 实践经验总结
本文详细演示了如何在现代 Ubuntu 系统中恢复并利用/etc/rc.local实现开机启动功能。通过创建rc-local.service服务单元,我们成功桥接了传统习惯与现代 systemd 架构之间的鸿沟。整个过程只需六步即可完成,且具备良好的可维护性和扩展性。
核心要点回顾: - 必须创建rc-local.service并启用 -/etc/rc.local必须有可执行权限且以exit 0结尾 - 推荐通过rc.local调用外部脚本而非直接写逻辑 - 出现问题优先使用systemctl status和journalctl排查
6.2 最佳实践建议
- 将
rc.local视为“启动调度器”,集中管理多个自启动任务 - 所有脚本使用绝对路径,避免相对路径引发的问题
- 关键操作添加日志输出,提升可观察性
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。