news 2026/2/7 8:19:19

看完就想试!让自己的脚本随系统一起启动

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
看完就想试!让自己的脚本随系统一起启动

看完就想试!让自己的脚本随系统一起启动

你有没有过这样的经历:写好了一个监控脚本、一个数据采集程序,或者一个自动备份工具,每次开机后都要手动打开终端、切换路径、敲命令才能运行?重复操作不仅费时,还容易忘记——尤其在服务器或嵌入式设备上,没人守着屏幕的时候,它就彻底“躺平”了。

其实,Linux系统早就为你准备好了“自动唤醒”的能力。不需要复杂配置,也不依赖图形界面,只要几步简单操作,就能让脚本在系统启动完成的第一时间安静而可靠地跑起来。本文不讲抽象原理,只聚焦一件事:怎么让你写的.sh文件,真正在开机时自动执行,并且稳稳当当地跑完

我们以 Ubuntu 22.04(及主流 Debian/Ubuntu 衍生版)为基准环境,全程使用终端操作,所有命令可直接复制粘贴,每一步都经过实测验证。即使你刚接触 Linux 不久,也能照着做成功。

1. 先写一个能“自证清白”的测试脚本

别急着改系统配置,先确保你的脚本本身是“健康”的——能独立运行、有明确输出、不报错。这是后续一切自动化的前提。

1.1 创建脚本文件

推荐放在一个清晰、易管理的位置,比如~/scripts(即当前用户的scripts文件夹)。如果目录不存在,我们顺手建一个:

mkdir -p ~/scripts cd ~/scripts

接着创建脚本文件,命名为startup_test.sh

nano startup_test.sh

在编辑器中输入以下内容(注意:第一行必须是#!/bin/bash,一个字符都不能错):

#!/bin/bash # 记录启动时间,方便验证是否真的执行了 echo "Script started at $(date)" > ~/startup_log.txt # 模拟一个实际任务:创建一个临时文件并写入内容 touch ~/test_run_flag echo "This script ran successfully on boot." > ~/test_run_flag # 可选:再加一行,证明它能执行多步操作 echo "Current user: $(whoami)" >> ~/startup_log.txt

小提示:~是当前用户的家目录缩写,等价于/home/你的用户名。用~更简洁,也避免硬编码用户名。

保存并退出(Nano 中按Ctrl+O→ 回车确认保存 →Ctrl+X退出)。

1.2 赋予执行权限

Linux 默认不会执行.sh文件,必须显式声明“这个文件可以运行”。用chmod命令添加执行权限:

chmod +x startup_test.sh

验证是否成功:运行ls -l startup_test.sh,你会看到最前面有一组权限位中包含x(如-rwxr-xr-x),说明已具备执行权。

1.3 手动运行一次,确认脚本没问题

这步不能跳!它帮你排除90%的后续失败原因:

./startup_test.sh

然后检查结果:

cat ~/startup_log.txt cat ~/test_run_flag

你应该看到类似这样的输出:

Script started at Mon Jun 10 15:22:34 CST 2024 Current user: yourusername

This script ran successfully on boot.

如果能看到这些内容,恭喜——你的脚本已经“活”了。接下来,就是让它“自己醒来”。

2. 选择最稳妥的启动方式:systemd 用户服务(推荐)

注意:网上很多教程还在教改rc.local,但它在较新版本 Ubuntu(18.04+)中默认被禁用,且需要 root 权限、修改系统级文件,既不安全也不优雅。而systemd 用户服务是现代 Linux 的标准方案:无需 root、作用域清晰、启停可控、日志可查,还支持开机延迟、失败重试等实用功能。

2.1 创建服务定义文件

systemd 通过.service文件来管理服务。我们在用户级目录下创建它,路径为~/.config/systemd/user/

mkdir -p ~/.config/systemd/user nano ~/.config/systemd/user/startup-test.service

填入以下内容(请逐字复制,注意空格和大小写):

[Unit] Description=My Startup Test Script After=network.target [Service] Type=oneshot ExecStart=/home/yourusername/scripts/startup_test.sh WorkingDirectory=/home/yourusername/scripts RemainAfterExit=yes [Install] WantedBy=default.target

关键字段说明:

  • Description:服务描述,纯文本,便于识别;
  • After=network.target:表示等网络就绪后再运行(如果你的脚本需要联网,这个很重要);
  • Type=oneshot:告诉 systemd 这是一个“执行完就结束”的一次性脚本(不是常驻进程);
  • ExecStart必须写绝对路径,把yourusername替换成你自己的用户名(可用whoami查看);
  • WorkingDirectory:指定脚本运行时的工作目录,避免路径错误;
  • RemainAfterExit=yes:让 systemd 认为服务“仍在运行”,方便后续状态查询。

保存退出后,刷新 systemd 用户配置:

systemctl --user daemon-reload

2.2 启用并立即测试服务

启用服务,让它在下次开机时自动运行:

systemctl --user enable startup-test.service

现在,我们不重启,而是立刻手动触发一次,验证服务定义是否正确:

systemctl --user start startup-test.service

检查状态:

systemctl --user status startup-test.service

如果看到active (exited)和绿色的,说明服务已成功执行。再检查日志:

journalctl --user -u startup-test.service -n 10 --no-pager

你会看到脚本输出的完整记录,包括时间戳和执行结果。

到此为止,你的脚本已经完全适配了 systemd 用户服务机制。下一步,就是让它真正“随系统启动”。

3. 让用户级服务在登录前就启动(关键一步)

默认情况下,systemd 用户服务是在你登录桌面或 SSH 会话后才启动的。但很多场景下,我们希望脚本在系统启动完成、甚至无人登录时就运行(比如服务器后台任务、树莓派无人值守设备)。

解决方法很简单:启用linger

sudo loginctl enable-linger $(whoami)

这条命令的作用是:告诉系统,“即使当前用户没登录,也要为我加载并运行用户级 systemd 服务”。

验证是否生效:

loginctl show-user $(whoami) | grep Linger

输出应为Linger=yes

这一步是区分“能用”和“真正可靠”的分水岭。没有它,你的脚本可能在远程服务器重启后根本不会运行。

4. 验证开机自启效果(不需重启整机)

虽然最终目标是开机运行,但频繁重启既耗时又影响工作。我们可以用更高效的方式模拟验证:

4.1 重启用户 session(等效于“登出再登录”)

systemctl --user restart dbus

然后重新加载服务状态:

systemctl --user daemon-reload systemctl --user start startup-test.service

再检查~/startup_log.txt,时间戳应该是最新的。

4.2 终极验证:重启系统

如果条件允许,执行一次完整重启:

sudo reboot

等待系统启动完毕、登录后,立即检查:

cat ~/startup_log.txt ls -l ~/test_run_flag

如果两个文件都存在,且时间戳是本次开机后的时间,说明——它真的做到了

5. 常见问题与避坑指南

实际部署中,几个看似微小的细节,往往导致脚本静默失败。以下是高频踩坑点和对应解法:

5.1 “脚本没执行,但 systemctl 显示 active”

原因:脚本内部命令路径错误(如cd到不存在的目录、调用未安装的命令)、权限不足、或环境变量缺失。

解决:

  • 在脚本开头添加set -e(遇到错误立即退出)和set -x(打印每条执行命令),便于定位:
    #!/bin/bash set -e set -x echo "Script started at $(date)" > ~/startup_log.txt
  • 所有外部命令(如python3,curl)使用绝对路径(which python3查看);
  • 避免依赖$HOME以外的环境变量,如需,显式导出:export PATH="/usr/local/bin:$PATH"

5.2 “日志里报 Permission denied”

常见于脚本尝试写入/var/log或其他系统目录。用户服务默认无 root 权限。

解决:永远把输出写到用户家目录下(如~/startup_log.txt),这是最安全、最无需额外配置的路径。

5.3 “脚本执行了,但里面的 GUI 程序打不开”

例如geditfirefox等图形程序,在无桌面会话时无法启动。

解决:这类程序不适合放开机脚本。如必须调用,请改用systemd --userType=forking并设置Environment=DISPLAY=:0,但强烈建议优先考虑无界面替代方案(如curl替代浏览器操作)。

5.4 “想让多个脚本按顺序执行”

不要在一个.sh里堆砌所有逻辑。更健壮的做法是:为每个独立任务创建单独的.service文件,然后用After=Wants=定义依赖关系。

例如,backup.service需要在network.service之后、database.service之前运行,只需在[Unit]段写:

After=network.service database.service Wants=network.service

6. 进阶技巧:让脚本更聪明、更可控

掌握了基础,你可以轻松叠加这些实用能力:

6.1 延迟启动,避开资源争抢

有些脚本依赖其他服务(如数据库、NFS挂载),刚开机时它们可能还没就绪。加个ExecStartPre就能优雅等待:

[Service] ExecStartPre=/bin/sleep 10 ExecStart=/home/yourusername/scripts/startup_test.sh

6.2 失败自动重试,提升鲁棒性

对于网络请求类脚本,加两行就能实现:

[Service] Restart=on-failure RestartSec=30

表示失败后等待30秒重试,最多重试5次(默认值)。

6.3 日志自动轮转,防止磁盘占满

[Service]段加入:

StandardOutput=append:/home/yourusername/logs/startup.log StandardError=append:/home/yourusername/logs/startup_error.log

再配合简单的 logrotate 配置,即可长期无忧。

总结

让脚本随系统启动,从来不是玄学,而是一套清晰、现代、安全的工程实践。本文带你绕开了老旧的rc.local陷阱,直接采用 Ubuntu 官方推荐的 systemd 用户服务方案,实现了:

  • 零 root 权限:所有操作都在用户空间完成,不碰系统核心文件;
  • 精准控制:可指定启动时机、失败策略、执行环境;
  • 可观测性强:一键查状态、看日志、重试服务;
  • 长期稳定linger机制确保无人登录时也能可靠运行。

你现在拥有的,不再是一个“能跑起来”的脚本,而是一个被系统正式接纳、受 systemd 统一管理的“数字员工”。它会在每个清晨安静就位,默默完成你交付的任务——而你要做的,只是写好那几十行清晰的 Bash 代码。

下一步,不妨把那个一直手动运行的数据同步脚本、日志清理工具,或者 IoT 设备心跳检测程序,照着本文流程迁移过来。你会发现,自动化带来的不只是效率,更是一种掌控感。


获取更多AI镜像

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

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

douyin-downloader:高效采集无水印视频的自媒体工具(5大突破)

douyin-downloader:高效采集无水印视频的自媒体工具(5大突破) 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader douyin-downloader是一款专为自媒体运营者、教育工作者、电商…

作者头像 李华
网站建设 2026/2/5 22:17:47

Qwen3-4B-Instruct-2507与DeepSeek-R1对比:编程能力评测实战

Qwen3-4B-Instruct-2507与DeepSeek-R1对比:编程能力评测实战 1. 为什么这次编程能力对比值得你花5分钟看完 你有没有遇到过这样的情况:写一段Python脚本处理Excel数据,反复调试却卡在边界条件上;或者想快速生成一个带错误处理的…

作者头像 李华
网站建设 2026/2/6 11:44:40

通义千问2.5-7B-Instruct性能优化:让推理速度提升3倍

通义千问2.5-7B-Instruct性能优化:让推理速度提升3倍 在实际部署Qwen2.5-7B-Instruct模型时,很多开发者会遇到一个共性问题:模型能力很强,但响应太慢。用户提问后要等5秒以上才出结果,Web界面卡顿、API超时频发&#…

作者头像 李华
网站建设 2026/2/6 15:53:52

游戏效率提升工具:绝区零一条龙全面使用指南

游戏效率提升工具:绝区零一条龙全面使用指南 【免费下载链接】ZenlessZoneZero-OneDragon 绝区零 一条龙 | 全自动 | 自动闪避 | 自动每日 | 自动空洞 | 支持手柄 项目地址: https://gitcode.com/gh_mirrors/ze/ZenlessZoneZero-OneDragon 绝区零一条龙是一款…

作者头像 李华