Ubuntu18.04开机自启难?测试脚本帮你搞定
你是不是也遇到过这样的情况:写好了服务脚本,反复检查路径、权限、依赖,重启后却纹丝不动?Ubuntu 18.04 的开机自启,不像老版本那样改个/etc/rc.local就完事——systemd 接管了启动流程,但默认又没配好rc-local.service,结果就是“脚本写了,系统不认,重启白忙”。
别急。这篇不是泛泛而谈的 systemd 理论课,也不是照搬手册的命令堆砌。它是一份专为 Ubuntu 18.04 实测验证过的开机自启实战指南,聚焦一个核心目标:用最简路径,让一个测试脚本稳稳当当在系统启动完成时自动跑起来。全程基于真实环境操作,每一步都经虚拟机反复验证,连卡在启动界面的坑都给你标清楚了。
我们不讲抽象概念,只做三件事:
用一个 5 行 shell 脚本作为统一测试载体(记录时间、主机名、写入文件)
对比三种主流方案在 Ubuntu 18.04 上的真实表现(rc.local / systemd 用户级 / systemd 系统级)
给出明确结论:哪种方案最省心、哪种最容易踩坑、哪种适合长期维护
现在,就从你的终端开始。
1. 先建一个“会说话”的测试脚本
所有自启方案最终都要调用一个脚本。我们先把它写好、测通,再挂到启动流程里。这个脚本不干别的,就做三件事:打时间戳、记主机名、写进指定文件——效果可验证、过程无依赖、失败有日志。
1.1 创建并验证脚本功能
打开终端,执行以下命令(建议全程使用普通用户,避免误操作):
# 在家目录下创建测试脚本 cat > ~/startup-test.sh << 'EOF' #!/bin/bash # 记录启动时间、主机名,并追加到日志文件 echo "=== $(date) ===" >> /tmp/startup-log.txt echo "Hostname: $(hostname)" >> /tmp/startup-log.txt echo "User: $(whoami)" >> /tmp/startup-log.txt echo "Uptime: $(uptime)" >> /tmp/startup-log.txt echo "" >> /tmp/startup-log.txt EOF # 赋予执行权限 chmod +x ~/startup-test.sh # 手动运行一次,确认能生成日志 ~/startup-test.sh # 查看结果 cat /tmp/startup-log.txt你应该看到类似这样的输出:
=== Mon Jun 10 14:23:45 CST 2024 === Hostname: ubuntu1804 User: user Uptime: 14:23:45 up 0 min, 1 user, load average: 0.12, 0.03, 0.01成功。这个脚本就是我们后续所有方案的“统一测试体”,它不依赖网络、不调用 GUI、不读写敏感路径,纯粹验证“系统能否在启动完成后准确执行你的命令”。
1.2 为什么不用 echo “hello” 这类极简脚本?
因为太容易“假成功”。比如echo "hello" > /tmp/hello.txt,如果/tmp分区还没挂载完,这条命令就静默失败;而我们的脚本带date和uptime,这两个命令必须等基础系统服务就绪才能返回有效值——这才是真正反映“启动完成”的信号。
2. 方案一:复活 rc.local(最接近传统习惯,但需手动补全)
Ubuntu 18.04 默认保留了/etc/rc.local文件位置,但rc-local.service单元被禁用且缺少关键配置。很多人试了sudo systemctl enable rc-local却失败,问题就出在这里。
2.1 检查并修复 rc-local.service
首先确认系统是否自带该服务单元:
ls /lib/systemd/system/rc-local*正常应输出/lib/systemd/system/rc-local.service。如果没看到,说明系统精简过度,需手动创建(但 Ubuntu 18.04 官方镜像通常自带)。
接着查看其内容:
sudo cat /lib/systemd/system/rc-local.service你会发现[Install]段缺失——这正是它默认无法启用的根本原因。我们来补上:
# 备份原文件 sudo cp /lib/systemd/system/rc-local.service /lib/systemd/system/rc-local.service.bak # 编辑服务定义,添加 Install 段 sudo sed -i '/\[Service\]/a [Install]\nWantedBy=multi-user.target\nAlias=rc-local.service' /lib/systemd/system/rc-local.service关键点:
WantedBy=multi-user.target表示该服务应在多用户模式(即标准命令行环境)启动后运行,这是绝大多数后台脚本的正确时机;Alias是为了兼容旧命令。
2.2 配置 /etc/rc.local 并赋予权限
创建或编辑/etc/rc.local:
sudo tee /etc/rc.local << 'EOF' #!/bin/bash # /etc/rc.local - executed at the end of each multiuser runlevel # Make sure the script is executable and runs before exit. # Call our test script in background (critical!) /home/user/startup-test.sh & # Always exit with 0 to avoid boot hang exit 0 EOF # 必须赋权,否则 systemd 会拒绝执行 sudo chmod 755 /etc/rc.local注意:末尾的&符号绝不能省!它让脚本在后台运行。若去掉,系统会卡在启动界面等待脚本结束(而我们的脚本没有退出逻辑),只能强制重启。
2.3 启用并验证
# 重新加载 systemd 配置 sudo systemctl daemon-reload # 启用 rc-local 服务(开机自启) sudo systemctl enable rc-local # 立即启动一次,无需重启 sudo systemctl start rc-local # 检查状态 sudo systemctl status rc-local状态应显示active (exited)。再看日志:
cat /tmp/startup-log.txt如果看到新追加的记录,说明rc.local方案已通。这是最贴近传统 Linux 习惯的方式,适合快速验证和临时需求。
3. 方案二:systemd 用户级服务(无需 root,适合个人应用)
如果你只是想让自己的脚本在登录后自动运行(比如启动一个本地 Web 服务、监控工具),systemd 用户级服务是更干净的选择——它不污染系统全局配置,且由当前用户完全控制。
3.1 创建用户级 service 文件
# 创建 systemd 用户服务目录(若不存在) mkdir -p ~/.config/systemd/user/ # 创建服务定义文件 cat > ~/.config/systemd/user/startup-test.service << 'EOF' [Unit] Description=Startup Test Script (User Level) After=network.target [Service] Type=oneshot ExecStart=/home/user/startup-test.sh RemainAfterExit=yes [Install] WantedBy=default.target EOF解释:
Type=oneshot表示脚本执行完即退出(非守护进程);RemainAfterExit=yes告诉 systemd:即使脚本结束了,服务状态仍视为“活跃”,方便状态查询;default.target对应用户登录后的默认环境。
3.2 启用并启动
# 重新加载用户级 systemd 配置 systemctl --user daemon-reload # 启用(登录时自动启动) systemctl --user enable startup-test.service # 立即启动一次 systemctl --user start startup-test.service # 查看状态 systemctl --user status startup-test.service成功后,cat /tmp/startup-log.txt会新增一条记录。下次你图形界面登录或 SSH 登录后,该脚本就会自动执行。
3.3 用户级 vs 系统级?何时选哪个?
- 选用户级:脚本只为你自己服务、不依赖 root 权限、需要随登录启动(如 IDE 插件、个人备份脚本)
- 选系统级:脚本需在无人登录时运行(如服务器 API、数据库)、需访问硬件设备、需 root 权限(如修改内核参数)
我们接下来就看系统级怎么搞。
4. 方案三:systemd 系统级服务(最规范,适合生产环境)
这是 Ubuntu 18.04 官方推荐的现代方式,配置一次,稳定可靠,且能被journalctl统一管理日志。
4.1 创建系统级 service 文件
# 创建服务文件到系统目录 sudo tee /etc/systemd/system/startup-test.service << 'EOF' [Unit] Description=Startup Test Script (System Level) After=multi-user.target Wants=multi-user.target [Service] Type=oneshot ExecStart=/home/user/startup-test.sh RemainAfterExit=yes User=user Group=user [Install] WantedBy=multi-user.target EOF关键配置:
User=user和Group=user指定以普通用户身份运行,避免脚本因 root 权限过高而失败(比如写入/tmp/时权限冲突);Wants=确保依赖关系明确。
4.2 启用并验证
# 重新加载全局 systemd 配置 sudo systemctl daemon-reload # 启用服务(开机自启) sudo systemctl enable startup-test.service # 立即启动 sudo systemctl start startup-test.service # 查看状态和实时日志 sudo systemctl status startup-test.service sudo journalctl -u startup-test.service -n 20 --no-pager如果状态为active (exited),且日志中无报错,说明系统级服务已就绪。此时即使系统无人登录,只要启动到多用户模式,脚本就会执行。
4.3 三个方案对比总结
| 维度 | rc.local 方案 | systemd 用户级 | systemd 系统级 |
|---|---|---|---|
| 适用场景 | 快速验证、兼容老脚本 | 个人应用、登录后启动 | 服务类程序、无人值守运行 |
| 配置复杂度 | 中(需补 service 文件) | 低(仅一个文件) | 中(需指定 User/Group) |
| 调试难度 | 高(日志分散,易卡启动) | 低(systemctl --user命令统一) | 低(journalctl日志集中) |
| 安全性 | 中(以 root 运行,权限过大) | 高(仅当前用户权限) | 高(可精确指定运行用户) |
| Ubuntu 18.04 兼容性 | 需手动修复 | 原生支持 | 原生支持 |
直接建议:
- 新项目、新服务 → 无脑选systemd 系统级(本文第4节)
- 个人小工具、不想碰 sudo → 选systemd 用户级(本文第3节)
- 临时调试、迁移老脚本 → 用rc.local(本文第2节),但务必加
&和exit 0
5. 常见问题与避坑指南(血泪经验)
这些不是理论假设,而是我们在 10+ 台 Ubuntu 18.04 虚拟机上踩出来的真坑。
5.1 重启后脚本没运行?先查这三处
权限是否到位?
rc.local文件必须755,service 文件必须644,脚本本身必须755。用ls -l逐个确认。路径是否绝对?
systemd 中ExecStart必须写绝对路径。~/startup-test.sh会失败,必须写/home/user/startup-test.sh。依赖是否满足?
如果你的脚本需要网络,After=network.target是必须的;如果需要文件系统挂载,加After=local-fs.target。我们测试脚本不依赖这些,所以没加。
5.2 日志在哪看?别再瞎猜
rc.local输出:默认重定向到/var/log/syslog,用grep rc.local /var/log/syslog查- systemd 用户级:
journalctl --user -u startup-test.service - systemd 系统级:
journalctl -u startup-test.service - 统一技巧:在脚本开头加
exec > /tmp/script-debug.log 2>&1,所有输出都会进这个文件,排查最直观。
5.3 为什么我改了 service 文件,systemctl restart却没生效?
因为systemctl restart只重启服务,不重载配置。每次修改.service文件后,必须执行:
sudo systemctl daemon-reload # 重载配置 sudo systemctl restart startup-test.service # 再重启服务漏掉第一句,等于白改。
6. 总结:Ubuntu 18.04 开机自启,其实很简单
回到最初的问题:“Ubuntu 18.04 开机自启难?”——难的不是技术本身,而是 Ubuntu 把启动管理权交给了更严谨但也更“啰嗦”的 systemd,而默认配置又留了个缺口。我们做的,不过是把那个缺口补上,然后选一条最顺的路走过去。
- 你只需要记住一个测试脚本:
~/startup-test.sh,它是你验证一切的基石。 - 你只需要掌握一种主力方案:对绝大多数人,
systemd 系统级服务(第4节)就是最优解——它规范、可查、可维护,且一次配置,十年无忧。 - 你只需要避开三个坑:
&符号、绝对路径、daemon-reload。填上它们,开机自启就再无玄学。
现在,关掉这篇博客,打开你的终端,用 5 分钟走一遍第4节的步骤。当你看到/tmp/startup-log.txt里出现第三条记录时,你就真正掌握了 Ubuntu 18.04 的开机自启。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。