news 2026/5/15 3:17:08

真实体验分享:成功实现开机写入日志到test.log

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
真实体验分享:成功实现开机写入日志到test.log

真实体验分享:成功实现开机写入日志到test.log

1. 背景与目标

最近在部署一个自动化任务时,遇到了一个常见但关键的问题:如何让系统在每次开机时自动执行一段脚本,并将运行结果记录到指定的日志文件中。我的目标非常明确——实现开机自动写入一条日志信息到/usr/local/test.log文件中

听起来很简单,但在 Ubuntu 18.04 及更高版本中,传统的rc.local方式默认已经被弃用。很多老教程不再适用,稍有不慎就会导致服务启动失败或系统卡住。本文将完整还原我从尝试、报错到最终成功的全过程,不跳过任何一个细节,适合和我一样想“稳稳落地”的朋友。

2. 为什么不能直接用 rc.local?

2.1 版本变化带来的兼容性问题

Ubuntu 从 16.04 开始逐步迁移到systemd作为初始化系统,到了 18.04 后,/etc/rc.local已经不再默认启用。即使你创建了这个文件,它也不会被执行,除非你手动配置相应的 systemd 服务来兼容它。

这就是为什么很多人发现:

  • 写好了/etc/rc.local
  • 给了可执行权限
  • 重启后却发现什么都没发生

根本原因:systemd 根本没去调用它

3. 解决方案:通过 systemd 恢复 rc.local 功能

我们不是要绕开 systemd,而是要“借它的力”,让它知道:请在开机时执行/etc/rc.local这个脚本。

3.1 创建 rc-local.service 服务单元

第一步是告诉 systemd:“我想用 rc.local,请为它注册一个服务”。

运行命令创建服务文件:

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

然后将以下内容粘贴进去:

[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:表示脚本会 fork 子进程后退出主进程(符合传统 SysVinit 行为)
  • RemainAfterExit=yes:即使脚本执行完毕,也认为服务仍在运行(因为是开机一次性任务)
  • WantedBy=multi-user.target:在多用户模式下启动,也就是正常开机状态

3.2 创建并配置 /etc/rc.local 脚本

接下来创建实际要执行的脚本文件:

sudo vim /etc/rc.local

输入以下内容:

#!/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

注意点

  • 必须以#!/bin/sh -e开头,-e表示遇到错误立即退出
  • 最后一定要有exit 0,否则 systemd 会认为脚本未正常结束
  • 日志路径/usr/local/test.log需要确保目录存在且可写

保存退出后,赋予可执行权限:

sudo chmod +x /etc/rc.local

3.3 启用并启动 rc-local 服务

现在让 systemd 加载我们的新服务:

sudo systemctl enable rc-local

这条命令的作用是:设置开机时自动启动该服务

接着,我们可以手动先启动一次,看看是否能立即生效:

sudo systemctl start rc-local.service

检查服务状态:

sudo systemctl status rc-local.service

如果一切顺利,你会看到类似这样的输出:

● rc-local.service - /etc/rc.local Compatibility Loaded: loaded (/etc/systemd/system/rc-local.service; enabled; vendor preset: enabled) Active: active (exited) since Mon 2025-04-05 10:20:12 CST; 1min ago

重点看两点:

  • Loaded: ... enabled:表示已启用
  • Active: active (exited):表示已成功执行并退出

3.4 验证日志是否生成

执行完服务后,查看日志文件是否存在:

cat /usr/local/test.log

你应该能看到输出:

看到这行字,说明添加自启动脚本成功。

恭喜!你已经完成了最关键的一步:让系统在当前会话中成功执行了 rc.local 脚本

4. 重启验证:真正的“开机自启”测试

前面只是手动启动了一次服务,真正的考验是——重启之后还能不能自动写入日志?

执行重启:

sudo reboot

等待系统重新启动完成后,再次查看日志文件:

cat /usr/local/test.log

如果你仍然能看到那句话,那就说明: 开机自启成功
日志写入成功
rc.local 被正确执行

5. 常见问题排查指南

尽管流程看似简单,但我第一次尝试时也失败了。以下是我在实践中遇到的真实问题及解决方案。

5.1 服务状态显示 failed

运行systemctl status rc-local.service显示:

Active: failed (Result: exit-code)

可能原因

  • /etc/rc.local没有exit 0
  • 脚本中有语法错误
  • 目标路径不可写(如/usr/local权限不足)

解决方法: 检查日志:

journalctl -u rc-local.service --since "1 hour ago"

你会看到具体的错误信息,比如:

/etc/rc.local: 10: cannot create /usr/local/test.log: Permission denied

这就说明权限有问题。可以尝试改用/tmp/test.log测试,或者确保/usr/local目录对 root 可写(通常没问题)。

5.2 中文字符导致脚本执行失败

这是我踩过的一个坑!

虽然 Linux 支持 UTF-8,但某些环境下,/etc/rc.local中包含中文会导致 systemd 执行失败。

比如这句:

echo "看到这行字,说明添加自启动脚本成功。" > /usr/local/test.log

如果系统 locale 设置不完整,可能会报错。

建议临时改为英文测试

echo "Startup script executed successfully." > /usr/local/test.log

确认功能正常后再换回中文,并确保系统语言环境配置正确。

5.3 rc-local.service 无法启用

运行systemctl enable rc-local报错:

Failed to enable unit: File /etc/systemd/system/rc-local.service already exists.

说明服务文件已存在,可能是之前创建重复了。可以先删除再重试:

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

然后再重新创建。

6. 进阶用法:用 rc.local 启动自定义脚本

上面的例子只是写一行日志,实际工作中我们更希望开机时运行自己的程序,比如 Python 脚本、Shell 脚本等。

下面演示如何通过rc.local调用外部脚本。

6.1 创建测试用的 Python 脚本

假设我们要在开机时运行一个 Python 脚本,向文件写入内容。

先创建脚本目录:

cd /home/lbw/

创建ce.py

with open("sb.txt", "w") as f: f.write("SB")

注意:这个脚本会在当前目录下生成sb.txt文件。

6.2 创建启动脚本 test.sh

为了方便管理,我们不直接在rc.local里写复杂命令,而是让它调用一个独立的.sh脚本。

创建test.sh

sudo vim /home/lbw/test.sh

内容如下:

#!/bin/bash cd /home/lbw/ python ce.py exit 0

赋予执行权限:

sudo chmod +x /home/lbw/test.sh

6.3 修改 rc.local 调用外部脚本

编辑/etc/rc.local

sudo vim /etc/rc.local

修改为:

#!/bin/sh -e # 调用自定义脚本 /home/lbw/test.sh exit 0

这样做的好处是:

  • rc.local保持简洁
  • 复杂逻辑放在外部脚本中,便于调试
  • 更容易扩展多个任务

6.4 重启验证效果

再次重启系统:

sudo reboot

登录后检查/home/lbw/sb.txt是否生成:

cat /home/lbw/sb.txt

如果看到输出SB,说明: Python 脚本被成功调用
自定义 Shell 脚本被执行
整个链路打通

7. 最佳实践与建议

经过这次完整的实践,我总结出几点实用建议,帮助你少走弯路。

7.1 推荐使用“索引式”rc.local

不要把所有逻辑都塞进/etc/rc.local,而是把它当作一个“启动入口”,只负责调用其他脚本。

例如:

#!/bin/sh -e # 启动数据同步脚本 /opt/scripts/start-sync.sh # 启动监控服务 /usr/local/bin/start-monitor.sh # 初始化网络配置 /etc/network/init-network.sh exit 0

这种方式更清晰、易维护。

7.2 使用绝对路径

rc.local和被调用脚本中,尽量使用绝对路径,避免因$PATH或工作目录不同而导致命令找不到。

错误示例:

python ce.py # 可能找不到 python 或 ce.py

正确做法:

/usr/bin/python3 /home/lbw/ce.py

7.3 添加日志记录以便调试

可以在脚本开头加一句时间戳日志,方便判断是否执行:

echo "$(date): Starting startup script..." >> /var/log/startup.log

这样即使主任务失败,也能通过日志确认执行时间。

7.4 注意文件权限和用户上下文

rc.local是以 root 身份运行的,所以:

  • 创建的文件属于 root
  • 如果你的应用需要普通用户权限运行,记得用su - username -c 'command'

例如:

su - lbw -c '/usr/bin/python3 /home/lbw/ce.py'

8. 总结

通过本次真实环境下的操作与排错,我们成功实现了“开机写入日志到test.log”的目标,并进一步扩展到了运行自定义脚本的能力。

回顾整个过程的关键步骤:

1. 创建rc-local.service兼容单元

2. 编写并授权/etc/rc.local脚本

3. 启用并测试rc-local.service

4. 重启验证日志生成

5. 排查常见问题(权限、中文、路径等)

6. 扩展至调用外部脚本(Shell + Python)

这套方法适用于绝大多数基于 systemd 的 Linux 发行版(如 Ubuntu 18.04+、Debian 10+、CentOS 7+),具有良好的通用性和稳定性。

只要记住一句话:在现代 Linux 中,想用rc.local,就必须先给它配一个 systemd 服务

掌握了这一点,你就拥有了一个简单而强大的开机自启工具。


获取更多AI镜像

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

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

OCR预处理怎么做?图像去噪增强配合cv_resnet18提效

OCR预处理怎么做?图像去噪增强配合cv_resnet18提效 1. 引言:为什么OCR前的图像预处理如此关键? 你有没有遇到过这样的情况:一张照片里的文字明明看得清,但扔给OCR模型就是识别不出来?或者识别结果乱码、漏…

作者头像 李华
网站建设 2026/5/14 22:43:45

学生党福音!低成本搭建PyTorch深度学习环境的方法

学生党福音!低成本搭建PyTorch深度学习环境的方法 1. 为什么学生更需要“开箱即用”的AI开发环境? 对于大多数学生来说,搞深度学习最头疼的不是模型不会调,而是环境装不上。明明代码写得没问题,一运行就报错&#xf…

作者头像 李华
网站建设 2026/5/10 8:48:55

杰理之左右声道数据调换【篇】

void ops_lr(void *buf, int len) { s16 *f_lrbuf; s16 tmp_l,tmp_r; lenlen>>2; for(int i0; i<len; i) ///lrlrlr...... {tmp_l f_lr[i*2];tmp_r f_lr[i*21];f_lr[i*21] tmp_l;f_lr[i*2] tmp_r; }}

作者头像 李华
网站建设 2026/5/3 0:39:08

开源大模型落地指南:Qwen3-14B企业级应用实战

开源大模型落地指南&#xff1a;Qwen3-14B企业级应用实战 1. 为什么是 Qwen3-14B&#xff1f;单卡时代的“守门员”选择 如果你正在寻找一个既能跑在消费级显卡上&#xff0c;又能扛住复杂任务的开源大模型&#xff0c;那 Qwen3-14B 很可能就是你现在最该关注的那个。 它不是…

作者头像 李华
网站建设 2026/5/9 12:45:10

专业级翻译落地实践|利用HY-MT1.5-7B实现高精度语义转换

专业级翻译落地实践&#xff5c;利用HY-MT1.5-7B实现高精度语义转换 在跨国商务谈判、国际法律事务和多语言内容发布的场景中&#xff0c;准确、高效的翻译能力已成为关键基础设施。然而&#xff0c;通用翻译工具常因术语不准、上下文割裂或格式错乱而难以胜任专业任务。面对这…

作者头像 李华
网站建设 2026/5/5 11:11:24

AutoGen Studio避坑指南:AI代理配置常见问题全解

AutoGen Studio避坑指南&#xff1a;AI代理配置常见问题全解 在使用AutoGen Studio构建多代理系统时&#xff0c;很多用户会遇到模型服务未启动、API调用失败、配置参数错误等常见问题。本文将结合实际部署经验&#xff0c;针对基于vllm运行Qwen3-4B-Instruct-2507模型的AutoG…

作者头像 李华