news 2026/4/15 12:21:53

不用再搜了!这才是Ubuntu开机启动脚本的正确写法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
不用再搜了!这才是Ubuntu开机启动脚本的正确写法

不用再搜了!这才是Ubuntu开机启动脚本的正确写法

1. 开机自启没你想的那么简单

你是不是也遇到过这种情况:写了个脚本,想让它开机自动运行,结果重启后发现根本没执行?或者明明配置好了rc.local,却始终不生效?

别急,这在 Ubuntu 上太常见了。尤其是从 16.04 开始,systemd 成为默认初始化系统后,很多老方法都失效或变得不稳定。网上搜一圈,各种教程五花八门,有的说改rc.local,有的教写 service 文件,还有的推荐用cron @reboot——但真正能稳定工作的少之又少。

今天这篇文章就是来终结混乱的。我会手把手带你实现一个稳定、可靠、可维护的开机启动方案,并告诉你为什么其他方式容易翻车。

我们以一个实际需求为例:
假设你有一个 Python 程序放在/home/ubuntu/myapp/start.py,希望它在每次开机时自动启动,并且有日志记录、失败能自动重启。

接下来,我会介绍三种主流方式,重点分析它们的优缺点,最后给出强烈推荐的最佳实践


2. 方法一:通过 /etc/rc.local 启动(兼容性尚可,但已过时)

2.1 原理简介

/etc/rc.local是传统的 Unix/Linux 开机脚本,在系统进入多用户模式前执行。虽然 Ubuntu 已转向 systemd,但仍保留了对它的兼容支持。

2.2 操作步骤

  1. 编辑文件:
sudo nano /etc/rc.local
  1. exit 0之前添加你的命令:
#!/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. # 任务开始 /home/ubuntu/myapp/start.py & echo "My app started via rc.local" >> /var/log/rc-local.log exit 0
  1. 给予执行权限:
sudo chmod +x /etc/rc.local
  1. 确保服务启用(某些版本需要):
sudo systemctl enable rc-local

2.3 存在的问题

  • 执行时机不确定:网络、挂载点可能还没准备好。
  • 无进程管理:程序崩溃后不会自动重启。
  • 权限问题多:普通用户路径下的脚本可能因环境变量缺失而失败。
  • Ubuntu 20.04+ 默认不启用:必须手动创建rc-local.service才能生效。

小贴士:如果你看到rc.local根本没运行,大概率是因为rc-local.service没被激活。可以用systemctl status rc-local查看状态。


3. 方法二:使用 cron 的 @reboot(简单但局限大)

3.1 原理说明

Cron 支持一种特殊语法@reboot,表示“仅在系统重启后运行一次”。适合轻量级任务。

3.2 配置方法

  1. 编辑当前用户的 cron 表:
crontab -e
  1. 添加一行:
@reboot /usr/bin/python3 /home/ubuntu/myapp/start.py >> /home/ubuntu/logs/boot.log 2>&1

3.3 优点与缺陷

优点缺点
配置简单,无需 root 权限只运行一次,无法监控进程
用户级配置,灵活脚本崩溃后不会重启
自带日志重定向方便环境变量可能不完整

实测反馈:这种方式看似简单,但在桌面环境或 GUI 登录前,GUI 相关操作会失败;服务器环境下倒是可用,但缺乏健壮性。


4. 方法三:编写 Systemd Service(强烈推荐!这才是正确姿势)

4.1 为什么这是最佳选择?

Systemd 是现代 Linux 的核心组件,具备以下优势:

  • 精确控制启动顺序(比如等网络就绪后再启动)
  • 自动重启机制
  • 资源隔离和限制
  • 完整的日志追踪(journalctl)
  • 状态管理(start/stop/status/restart)

这才是符合当前技术趋势的正规军打法。

4.2 创建服务文件

  1. 新建服务配置:
sudo nano /etc/systemd/system/myapp.service
  1. 写入以下内容(请根据实际情况修改路径和用户名):
[Unit] Description=My Custom Startup Application After=network.target syslog.target Wants=network.target [Service] Type=simple User=ubuntu WorkingDirectory=/home/ubuntu/myapp ExecStart=/usr/bin/python3 /home/ubuntu/myapp/start.py Restart=always RestartSec=10 StandardOutput=journal StandardError=journal SyslogIdentifier=myapp [Install] WantedBy=multi-user.target
参数解释:
  • After=network.target:确保网络已启动
  • User=ubuntu:指定运行用户,避免权限问题
  • Restart=always:崩溃后自动重启
  • RestartSec=10:每次重启间隔 10 秒
  • StandardOutput=journal:日志由 systemd 统一收集

4.3 启用并测试服务

  1. 重载 systemd 配置:
sudo systemctl daemon-reexec sudo systemctl daemon-reload
  1. 启动服务:
sudo systemctl start myapp
  1. 查看状态:
sudo systemctl status myapp
  1. 设置开机自启:
sudo systemctl enable myapp
  1. 实时查看日志:
journalctl -u myapp -f

你会发现输出非常清晰,包括时间戳、PID、错误信息等,调试起来极其方便。


5. 常见坑点与避坑指南

5.1 路径问题导致脚本找不到

很多人写的脚本里用了相对路径或~,但在 systemd 环境下工作目录不一定是家目录。

正确做法:

  • 使用绝对路径
  • 显式设置WorkingDirectory

❌ 错误示例:

ExecStart=python3 ~/myapp/start.py

正确写法:

WorkingDirectory=/home/ubuntu/myapp ExecStart=/usr/bin/python3 start.py

5.2 权限不足无法访问设备或端口

如果程序要绑定 80 端口、访问 GPIO 或 USB 设备,可能会因权限不足失败。

解决方案:在[Service]中添加能力声明。

例如允许绑定低端口:

AmbientCapabilities=CAP_NET_BIND_SERVICE

或访问串口设备:

ReadWritePaths=/dev/ttyUSB0

5.3 依赖服务未就绪就启动

比如数据库还没启动完,你的应用就开始连接,必然失败。

解决方案:合理使用AfterWants

常见组合:

After=network.target postgresql.service Wants=postgresql.service

5.4 日志看不见?学会用 journalctl

别再盲目查.log文件了!systemd 提供强大的日志工具:

# 查看服务最新日志 journalctl -u myapp -n 50 # 实时跟踪日志 journalctl -u myapp -f # 查看某次启动的日志 journalctl -u myapp --since today # 查看上次启动的日志 journalctl -u myapp -b -1

这些命令比 grep 文本高效得多。


6. 总结:这才是你应该掌握的正确姿势

6.1 三种方式对比一览表

方式是否推荐适用场景稳定性可维护性
/etc/rc.local❌ 不推荐快速验证、临时任务
cron @reboot谨慎使用用户级简单脚本
systemd service强烈推荐所有生产级应用

6.2 最佳实践清单

  1. 优先使用 systemd service,这是现代 Linux 的标准方式
  2. 写清楚DescriptionAfter,提升可读性和可靠性
  3. 设置Restart=always,让程序具备自愈能力
  4. journalctl查日志,告别分散的日志文件
  5. 测试时先手动start,确认无误再enable
  6. 避免在服务中调用 GUI 程序(除非是桌面服务)

6.3 给新手的建议

如果你刚接触 Linux 自启动,记住一句话:

“凡是能用 systemd service 实现的,就不要再碰rc.localcron @reboot。”

这不是炫技,而是为了系统的长期稳定。你现在花半小时学会写 service 文件,未来能省下无数个凌晨爬起来修故障的时间。

而且一旦掌握,你会发现它比那些“简单”的方法更直观、更可控、更专业。


获取更多AI镜像

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 12:14:13

零基础玩转YOLO26:官方镜像保姆级教程

零基础玩转YOLO26:官方镜像保姆级教程 你是不是也曾经被目标检测的复杂环境配置劝退?下载依赖、编译框架、调试版本冲突……光是准备阶段就能耗掉一整天。现在,这一切都成了过去式。 今天要介绍的 “最新 YOLO26 官方版训练与推理镜像”&am…

作者头像 李华
网站建设 2026/4/14 18:47:39

如何判断是否需要GPEN修复?这3种情况最适用

如何判断是否需要GPEN修复?这3种情况最适用 1. 老照片模糊褪色,细节严重丢失 1.1 常见问题表现 你有没有翻出过家里的老相册,想看看父母年轻时的模样,却发现照片早已泛黄、模糊不清?或者某张珍贵的合影因为年代久远…

作者头像 李华
网站建设 2026/3/28 6:15:24

小白也能用!SenseVoiceSmall语音理解镜像保姆级入门教程

小白也能用!SenseVoiceSmall语音理解镜像保姆级入门教程 你是不是也遇到过这样的问题:一段音频里既有说话内容,又有背景音乐、笑声或情绪波动,但普通语音转文字工具只能输出干巴巴的文字?现在,阿里开源的 …

作者头像 李华