news 2026/4/16 5:10:05

初学者福音:图文并茂讲解开机自启全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
初学者福音:图文并茂讲解开机自启全流程

初学者福音:图文并茂讲解开机自启全流程

你是不是也遇到过这样的问题:写好了Python脚本,想让它开机自动运行,结果重启后发现什么都没发生?试了网上各种方法,不是报错就是没反应,最后只能手动点开终端再执行一遍……别急,这篇文章就是为你准备的。我会用最直白的语言、最清晰的步骤、最贴近真实操作的截图逻辑(文字描述代替图片),带你从零搞定Linux系统下的开机自启——不讲虚的,不堆术语,每一步都可复制、可验证、可排查。

全文基于Ubuntu 20.04/22.04等现代systemd系统(兼容18.04及以上),完全避开老旧rc.local失效的坑,手把手带你重建一个稳定、可靠、易维护的开机启动机制。哪怕你刚接触Linux三天,只要会敲几行命令,就能顺利完成。


1. 为什么老办法不管用了?

在Ubuntu 14.04时代,大家习惯直接编辑/etc/rc.local文件,加一行脚本就完事。但自16.04起,Ubuntu全面转向systemd管理服务,rc.local默认被禁用,不是文件不存在,而是它根本不被执行

你可能会看到这些典型现象:

  • 编辑完/etc/rc.local并加了chmod +x,重启后cat /var/log/syslog | grep rc.local却查不到任何记录
  • 手动运行sudo /etc/rc.local能成功,但开机时就是不触发
  • systemctl status rc-local显示inactive (dead)failed

这不是你写错了,是系统底层机制变了。我们不再“修复”rc.local,而是给它配一个systemd服务容器,让它重新被系统识别和调度——这才是现代Linux的正确打开方式。


2. 核心思路:用systemd“托住”你的启动脚本

整个流程其实就三件事:

  • 写一个systemd服务单元文件(告诉系统:“这个脚本我需要开机跑”)
  • 写一个真正的启动脚本(比如test.sh,里面调用你的Python程序)
  • 把脚本和权限、路径、执行环境都配对(避免“找不到python”“路径不对”“中文乱码”等新手高频雷)

下面所有操作,我都按真实终端顺序展开,命令可直接复制粘贴,关键位置我会说明“为什么这么写”。


2.1 创建systemd服务文件:rc-local.service

打开终端,执行:

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

推荐用nano而非vim,对新手更友好(按Ctrl+O保存,Ctrl+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

重点解释这几句

  • ConditionPathExists=/etc/rc.local:只有当/etc/rc.local文件存在时,这个服务才启动——避免误启
  • Type=forking:因为rc.local本身会fork子进程,必须声明类型,否则systemd会误判为“启动失败”
  • RemainAfterExit=yes:表示即使rc.local执行完了,服务状态仍保持“active”,方便后续依赖判断
  • WantedBy=multi-user.target:这是Linux多用户模式的目标,相当于“系统准备好后就运行它”

2.2 创建并配置 /etc/rc.local 启动索引文件

现在创建真正的启动入口文件:

sudo nano /etc/rc.local

粘贴以下内容(第一行必须是#!/bin/sh -e,结尾必须有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. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # 下面这行是测试用:重启后检查 /usr/local/test.log 是否生成 echo "开机自启服务已激活" > /usr/local/test.log # 这里是你真正要运行的脚本(推荐放在这里统一调度) # 注意:路径必须写绝对路径,不能用 ~ 或 $HOME sh /home/yourusername/test.sh exit 0

重要提醒

  • 把上面的yourusername换成你自己的用户名(如ubuntujohn),可用whoami命令确认
  • sh /home/.../test.sh是调用你自己的脚本,不是直接写Python命令——这样更安全、更易调试

2.3 给rc.local加执行权限

sudo chmod +x /etc/rc.local

这一步不能省!Linux下任何脚本要被执行,必须有x权限。没有这行,systemd会静默跳过。


2.4 启用并启动服务

启用服务(让系统记住“下次开机要运行它”):

sudo systemctl enable rc-local.service

立即启动一次(不用重启也能验证):

sudo systemctl start rc-local.service

检查是否成功:

sudo systemctl status rc-local.service

正常输出中应包含:

  • Active: active (exited)active (running)
  • Loaded: loaded (/etc/systemd/system/rc-local.service; enabled; vendor preset: enabled)
  • 最后一行类似Started /etc/rc.local Compatibility

❌ 如果显示failed,别慌——直接看下一条。


3. 常见失败原因与排查指南(新手必读)

90%的开机自启失败,都出在这几个地方。我们逐个击破:


3.1 日志查看:第一手线索

无论状态显示如何,最准的判断方式是看日志:

sudo journalctl -u rc-local.service -n 50 --no-pager
  • -n 50:显示最近50行
  • --no-pager:不翻页,直接输出到终端

你会看到类似这样的关键信息:

Mar 15 10:22:33 ubuntu systemd[1]: Starting /etc/rc.local Compatibility... Mar 15 10:22:33 ubuntu rc.local[1234]: /etc/rc.local: 15: sh: /home/ubuntu/test.sh: Permission denied

→ 看到Permission denied?说明test.sh没加执行权限,回退到2.5节补上。

再比如:

Mar 15 10:22:33 ubuntu rc.local[1234]: /etc/rc.local: 15: sh: python: not found

→ 说明脚本里写的python命令系统找不到,可能是没装,或该用python3


3.2 脚本路径与环境变量陷阱

你在终端里能运行python3 ce.py,不代表开机时也能。原因有两个:

  • 路径是相对的:开机时当前目录是/,不是你的家目录
  • PATH环境变量不同:systemd服务默认PATH极简(通常只有/usr/bin:/bin),不包含你.bashrc里加的路径

正确做法:

  • 所有路径写绝对路径/home/xxx/test.sh,不是./test.sh
  • Python脚本里,用#!/usr/bin/env python3开头,或直接写python3 /home/xxx/ce.py
  • 不要依赖source ~/.bashrc—— 它在systemd环境下根本不会加载

3.3 中文字符与编码问题(隐藏杀手)

参考博文里提到:“我犯得错误就是py文件存在中文,而无法运行”。这是真事。

Python 2默认ASCII,Python 3虽支持UTF-8,但systemd启动时LANG可能未设置,导致读取含中文的.py文件报错:

SyntaxError: Non-UTF-8 code starting with '\xe4' in file /home/xxx/ce.py

解决方案(二选一):

  • 推荐:Python脚本里第一行加编码声明:
    # -*- coding: utf-8 -*- with open("sb.txt", "w") as f: f.write("SB")
  • 或者:彻底避免脚本中出现中文(变量名、注释、字符串都用英文)

4. 实战:部署你的第一个开机脚本(以Python为例)

我们来走一遍完整闭环:从写代码 → 写shell → 配置启动 → 验证结果。


4.1 写一个简单的Python程序

假设你想开机自动创建一个标记文件:

nano /home/$(whoami)/ce.py

内容如下(注意:无中文,路径绝对):

#!/usr/bin/env python3 import os # 写入当前时间戳,证明是开机时运行的 with open("/tmp/autostart_marker.txt", "w") as f: f.write(f"Auto-started at {os.popen('date').read().strip()}\n") print(" Python脚本已执行")

os.popen('date')是为了演示动态内容,实际项目中建议用datetime.now()更规范


4.2 写调用它的shell脚本

nano /home/$(whoami)/test.sh

内容如下(注意:指定python3,用绝对路径):

#!/bin/bash # 切换到脚本所在目录(可选,但推荐) cd /home/$(whoami) # 执行Python脚本 /usr/bin/python3 /home/$(whoami)/ce.py # 可选:记录日志便于排查 echo "$(date): ce.py executed" >> /tmp/autostart.log

加执行权限:

chmod +x /home/$(whoami)/test.sh

4.3 更新rc.local,指向你的脚本

回到/etc/rc.local,确保最后一段是:

sh /home/$(whoami)/test.sh exit 0

(再次确认:$(whoami)已替换为真实用户名)


4.4 验证与重启测试

先手动触发一次:

sudo /etc/rc.local

检查结果:

cat /tmp/autostart_marker.txt # 应输出类似:Auto-started at Mon Mar 15 10:30:22 CST 2024 cat /tmp/autostart.log # 应有时间戳记录

一切正常后,重启验证终极效果:

sudo reboot

等待系统起来后,直接运行:

cat /tmp/autostart_marker.txt

如果看到带时间戳的内容,恭喜你——开机自启已稳稳落地。


5. 进阶建议:让启动更健壮、更可控

你已经掌握了核心流程,下面这几个小技巧,能让日常维护事半功倍:


5.1 用systemd原生方式替代rc.local(更推荐)

如果你只启动一个脚本,其实可以直接写专属service,无需绕路rc.local:

sudo nano /etc/systemd/system/myapp.service

内容示例:

[Unit] Description=My Python App Auto Start After=network.target [Service] Type=simple User=yourusername WorkingDirectory=/home/yourusername ExecStart=/usr/bin/python3 /home/yourusername/ce.py Restart=always RestartSec=10 [Install] WantedBy=multi-user.target

启用它:

sudo systemctl daemon-reload sudo systemctl enable myapp.service sudo systemctl start myapp.service

优势:

  • 每个应用独立管理,互不影响
  • Restart=always自动崩溃恢复
  • User=指定运行用户,避免root权限滥用
  • 日志统一归集:journalctl -u myapp.service

5.2 启动延迟与依赖控制

有些脚本依赖网络、数据库或GPU驱动,需等它们就绪再运行:

  • After=network.target:等网络通了再启动
  • After=postgresql.service:等PostgreSQL启动后再运行
  • Wants=network.target:声明强依赖

查看系统所有target:systemctl list-units --type=target


5.3 日志轮转与清理(防磁盘占满)

长期运行的脚本,日志容易暴涨。加一行到service文件里:

[Service] ... StandardOutput=append:/var/log/myapp.log StandardError=append:/var/log/myapp.log

再配个logrotate(新建/etc/logrotate.d/myapp):

/var/log/myapp.log { daily missingok rotate 30 compress delaycompress notifempty }

6. 总结:你已掌握的不仅是“开机自启”,更是Linux服务思维

回顾一下,你今天完成了:

  • 理解了systemd与传统init的本质区别
  • 搭建了可复用的rc-local兼容服务框架
  • 成功部署并验证了Python脚本的开机自启
  • 掌握了三大高频故障(权限、路径、编码)的定位与解决方法
  • 学会了用journalctl看日志、用systemctl管服务、用logrotate护日志

这不是一个“一次性技巧”,而是一套可迁移的能力:以后部署Flask网站、启动TensorFlow训练、挂载NAS存储……底层逻辑一脉相承。

最后送你一句实操口诀:
“脚本写绝对路径,权限必须加x,日志先看journal,报错别猜靠证据。”


获取更多AI镜像

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

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

InstructPix2Pix跨平台适配:移动端轻量化部署探索

InstructPix2Pix跨平台适配:移动端轻量化部署探索 1. 为什么需要把InstructPix2Pix搬到手机上? 你有没有过这样的经历:在旅行途中拍到一张绝美夕阳照,突然想试试“把天空换成极光”,但手边只有手机?或者朋…

作者头像 李华
网站建设 2026/4/13 22:22:23

MedGemma 1.5详细步骤:支持中英文混输的离线病理分析系统搭建

MedGemma 1.5详细步骤:支持中英文混输的离线病理分析系统搭建 1. 为什么你需要一个本地化的医学AI助手? 你有没有遇到过这样的情况:手头有一份病理报告,上面密密麻麻写着“腺体结构紊乱”“核异型性明显”“间质淋巴细胞浸润”&…

作者头像 李华
网站建设 2026/4/13 23:29:56

YOLOE-s/m/l系列模型对比,哪个更适合你?

YOLOE-s/m/l系列模型对比,哪个更适合你? YOLOE不是又一个“YOLO套壳”模型。当你第一次在终端里敲下 python predict_text_prompt.py --names "teddy bear, coffee mug",看着一张普通生活照里被精准框出、分割出、甚至从未在训练数…

作者头像 李华
网站建设 2026/4/15 20:56:02

ChatGLM3-6B-128K效果展示:Ollama部署本地大模型生成128K小说世界观设定

ChatGLM3-6B-128K效果展示:Ollama部署本地大模型生成128K小说世界观设定 1. 为什么128K上下文对小说创作如此关键? 你有没有试过让AI帮你构建一个完整的小说世界?比如,一座有千年历史的浮空城邦,它的政治结构、宗教信…

作者头像 李华