小白友好教程:无需复杂操作,轻松实现自启动
你是不是也遇到过这样的问题:写好了一个监控脚本、一个数据采集程序,或者一个自动备份工具,每次重启服务器后都要手动运行一次?反复操作既费时又容易遗漏。更让人头疼的是,网上搜到的教程动不动就让你改配置、查日志、调服务,光看命令就头大——别担心,这篇教程专为“不想折腾”的人设计。
它不讲 systemd 原理,不分析依赖关系,也不要求你背命令;只用 6 个清晰步骤,带你把一个普通.sh脚本变成开机自动运行的“隐形助手”。整个过程不需要编译、不涉及内核参数、不修改系统关键文件结构,所有操作都在/etc/rc.local这一个入口点完成。哪怕你刚学会ls和cd,也能照着做成功。
更重要的是,这个方法稳定、通用、易排查——Ubuntu 18.04 及之后版本(20.04、22.04、24.04)都适用,且和桌面版、服务器版、Docker 容器内环境兼容。我们不追求“最优雅”,只确保“第一次就能跑通”。
下面就开始吧。你只需要打开终端,一条命令一条命令地敲,每一步都有明确目的和即时反馈,失败了也能立刻知道哪里出了问题。
1. 先确认系统支持 rc.local 方式
Ubuntu 18.04 开始,默认禁用了传统的/etc/rc.local启动机制,但它并没有删除这个功能,只是需要手动“唤醒”一下。这就像给一台老式收音机换上新电池——硬件还在,只是开关没打开。
我们先检查当前系统是否已启用该机制:
systemctl list-unit-files | grep rc-local如果看到类似这样的输出:
rc-local.service disabled说明它目前是关闭状态,正好是我们要操作的对象。如果显示enabled或static,也可以继续往下走,后续步骤会帮你校准。
小提示:这条命令只是“摸底”,不改变任何东西,放心执行。
2. 创建 rc-local.service 服务定义文件
现在我们要告诉系统:“请在开机时,记得去执行/etc/rc.local这个文件。”
这一步就是创建一个“服务说明书”,让 systemd 知道该怎么对待rc.local。
执行以下命令新建文件:
sudo nano /etc/systemd/system/rc-local.service推荐用
nano而不是vim,因为nano更直观:底部有操作提示(如^O保存、^X退出),对新手更友好。
把下面这段内容完整复制粘贴进去(注意大小写和空格):
[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保存并退出:按Ctrl+O→ 回车确认保存 → 按Ctrl+X退出。
这个文件的作用,简单说就是“给 rc.local 打个补丁”,让它能被现代 Ubuntu 正确识别和调用。你不用理解每一行含义,只要知道:这是官方推荐的兼容方案,安全、无副作用。
3. 创建并编辑 /etc/rc.local 启动脚本
接下来,我们真正创建那个“开机自动执行”的入口文件。
运行命令:
sudo nano /etc/rc.local把下面内容完整粘贴进去(注意第一行必须是#!/bin/sh -e,一个字符都不能错):
#!/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保存退出(Ctrl+O→ 回车 →Ctrl+X)。
特别注意两个关键点:
- 第一行
#!/bin/sh -e是“脚本声明”,告诉系统用什么解释器运行它。漏掉或写错会导致整个自启动失败。 - 最后一行
exit 0是“成功信号”,表示脚本顺利结束。没有它,系统会认为启动出错而中断后续流程。
这个文件现在的作用,是开机时往/usr/local/test.log写一句话。它只是一个“探针”,用来验证整套机制是否打通。等你确认它能工作,再替换成你自己的脚本。
4. 设置权限并启用服务
Linux 对启动脚本有严格权限要求:它必须是“可执行”的,否则系统会直接跳过。
执行命令,给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.这表示系统已记住:“下次开机,请务必运行 rc-local.service。”
小知识:
systemctl enable不会立即运行服务,它只是设置“开机自启”。真正的运行要等到重启后,或我们手动触发。
5. 手动启动并验证是否生效
现在我们不重启,而是用“热启动”方式快速验证整条链路是否通畅。
先手动启动服务:
sudo systemctl start rc-local.service再检查它的运行状态:
sudo systemctl status rc-local.service如果一切正常,你会看到类似这样的关键信息:
Active: active (exited) since ... ... Process: ... ExecStart=/etc/rc.local start (code=exited, status=0/SUCCESS)其中active (exited)和status=0/SUCCESS是两个黄金指标,说明服务已成功执行完毕。
最后,检查日志文件是否生成:
cat /usr/local/test.log你应该看到:
看到这行字,说明添加自启动脚本成功。恭喜!你已经打通了从系统启动到脚本执行的全部环节。这个“测试探针”证明:你的 Ubuntu 已经准备好为你运行任何自定义任务。
6. 把你的脚本正式接入自启动
前面的test.log只是验证用的。现在,我们把它替换成你真正想开机运行的程序。
假设你想开机自动运行一个 Python 脚本ce.py,它位于/home/yourname/目录下,功能是生成一个sb.txt文件。
6.1 创建你的实际脚本
先创建一个 shell 包装器(wrapper),这是最稳妥的做法:
sudo nano /home/yourname/test.sh输入以下内容(请把yourname替换成你自己的用户名):
#!/bin/bash cd /home/yourname/ python3 ce.py exit 0保存退出。
再给它加上执行权限:
sudo chmod +x /home/yourname/test.sh6.2 编写你的 Python 脚本
接着创建ce.py:
nano /home/yourname/ce.py输入内容:
with open("/home/yourname/sb.txt", "w") as f: f.write("SB")注意:这里我们把路径写成绝对路径
/home/yourname/sb.txt,避免因工作目录不确定导致文件写入失败。
6.3 修改 rc.local,调用你的脚本
现在回到/etc/rc.local,把它从“测试模式”切换到“生产模式”:
sudo nano /etc/rc.local把原来那行echo ... > /usr/local/test.log删除,替换成调用你刚写的test.sh:
#!/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. # 下面这一行是你新增的,调用你的脚本 /home/yourname/test.sh exit 0保存退出。
6.4 重启验证最终效果
执行重启命令:
sudo reboot等待系统重新启动后,登录进去,检查你的成果:
cat /home/yourname/sb.txt如果输出SB,说明你的 Python 脚本已在开机时自动运行成功。
🛠 如果没成功?别急,用这句命令查原因:
sudo systemctl status rc-local.service它会显示最后一次执行的详细日志,常见问题包括:路径写错、Python 命令名不对(比如该用
python3却写了python)、脚本里有中文注释未声明编码等。
7. 实用技巧与避坑指南
这套方法看似简单,但在真实环境中常因几个细节“卡壳”。以下是我们在上百次部署中总结出的高频问题和应对方案,帮你省下查文档、翻日志的时间。
7.1 路径问题:永远用绝对路径
你在test.sh里写的cd /home/yourname/是对的,但如果你在ce.py里用相对路径写文件,比如open("sb.txt", "w"),它可能写到/root/或/根目录下,而不是你预期的位置。
正确做法:所有文件读写、程序调用,一律使用绝对路径。例如:
python3 /home/yourname/ce.pytouch /home/yourname/log.txtcurl -o /tmp/data.json https://api.example.com
7.2 Python 环境问题:明确指定解释器
Ubuntu 系统可能同时装有python(2.7)、python3(3.x),甚至你用pyenv或conda管理了多个版本。/etc/rc.local默认用系统sh执行,它不认识你的虚拟环境。
解决方案有两个:
- 推荐:在
test.sh中显式激活环境,例如:#!/bin/bash cd /home/yourname/ source /home/yourname/myenv/bin/activate python ce.py deactivate exit 0 - 更简单:直接用完整路径调用 Python,例如:
/home/yourname/myenv/bin/python /home/yourname/ce.py
7.3 权限问题:脚本和目标目录都要有写入权
如果你的脚本要往/var/www/html/写网页,或往/opt/app/写日志,而当前用户(通常是root)没有对应目录的写权限,就会静默失败。
快速检查法:
sudo -u root ls -ld /var/www/html/如果输出中没有w(写权限),就加:
sudo chmod 755 /var/www/html/ # 或更安全地,只给组或用户加写权限7.4 启动时机问题:有些服务还没起来
rc.local在multi-user.target阶段执行,此时网络、数据库、GPU 驱动等可能尚未就绪。如果你的脚本依赖 MySQL 或需要联网,可能启动失败。
应对策略:
- 加延时(不推荐,治标不治本):
sleep 10 && /home/yourname/test.sh - 推荐:改用
systemd服务,并设置After=network.target mysqld.service,但这已超出本教程范围。当前方案下,优先确保你的脚本具备重试逻辑或失败容忍能力。
8. 总结:你已经掌握了一项关键运维能力
回顾一下,你刚刚完成了什么:
- 让 Ubuntu 18.04+ 重新支持经典
rc.local启动方式; - 创建了一个可执行的 shell 包装器,安全调用任意脚本;
- 成功让 Python 程序在每次开机时自动运行;
- 掌握了快速验证、定位失败原因的核心命令;
- 学会了处理路径、权限、环境等真实世界中的典型障碍。
这不是一个“玩具实验”,而是一套经过生产环境验证的轻量级自启动方案。它比写复杂的 systemd unit 文件更简单,比 crontab 的@reboot更可靠,比 Docker 的 restart policy 更底层可控。
你可以用它来:
- 自动拉取最新代码并重启服务;
- 开机初始化数据库表结构;
- 启动一个本地 Web 服务供内网访问;
- 定期清理临时文件,保持磁盘健康;
- 甚至作为物联网设备的“开机管家”,协调多个传感器进程。
技术的价值,不在于它多炫酷,而在于它能否安静、稳定、不声不响地为你干活。现在,你的服务器已经拥有了这份“安静的力量”。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。