news 2026/4/23 15:25:03

不用再搜了!这才是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/18 11:03:48

开源ASR流水线搭建:FSMN-VAD作为前端模块教程

开源ASR流水线搭建:FSMN-VAD作为前端模块教程 1. FSMN-VAD 离线语音端点检测控制台 你是否在处理长段录音时,为手动切分有效语音片段而头疼?传统方式不仅耗时,还容易遗漏关键信息。现在,借助达摩院开源的 FSMN-VAD 模…

作者头像 李华
网站建设 2026/4/20 16:36:48

如何成功制备与筛选应用于双抗夹心ELISA的配对抗体?

一、为何双抗夹心ELISA必须使用配对抗体?双抗夹心酶联免疫吸附测定(Sandwich ELISA)是检测和定量复杂样本中特定抗原(尤其是蛋白质)最常用且最可靠的方法之一。其高特异性和灵敏度的核心在于使用一对能够同时、且非竞争…

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

惊艳!Qwen All-in-One打造的情感分析+对话案例展示

惊艳!Qwen All-in-One打造的情感分析对话案例展示 1. 引言:一个模型,两种能力 你有没有想过,一个AI模型不仅能听懂你说话的情绪,还能像朋友一样回应你?听起来像是科幻电影里的场景,但今天&…

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

Llama3 vs DeepSeek-R1实战对比:蒸馏模型性能评测

Llama3 vs DeepSeek-R1实战对比:蒸馏模型性能评测 1. Meta-Llama-3-8B-Instruct:轻量级对话模型的新标杆 Meta-Llama-3-8B-Instruct 是 Meta 在 2024 年 4 月推出的开源指令微调模型,作为 Llama 3 系列中的中等规模版本,它在保持…

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

requirements.txt生成效率提升10倍?这3个冷门但超实用的命令你用过吗?

第一章:requirements.txt生成效率提升的认知革命 在现代Python开发中,依赖管理已成为项目可维护性与协作效率的核心环节。传统的手动编写 requirements.txt 文件方式不仅耗时,还容易因环境差异导致版本冲突。一场关于依赖文件生成效率的认知…

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

IQuest-Coder-V1-40B-Instruct环境部署:Ubuntu下完整指南

IQuest-Coder-V1-40B-Instruct环境部署:Ubuntu下完整指南 你是否正在寻找一款真正能理解代码演化逻辑、具备强大推理能力的代码大模型?IQuest-Coder-V1-40B-Instruct 正是为此而生。它不是简单的代码补全工具,而是一个面向软件工程和竞技编程…

作者头像 李华