咨询:Linux服务器生命周期内仅执行一次开机脚本的实现方案
可行实现方案
方案1:使用systemd的oneshot服务(推荐现代Linux系统)
适用于Ubuntu、CentOS 7+等采用systemd初始化的主流发行版,是最规范的实现方式:
- 先将脚本从
/tmp迁移到稳定目录(/tmp会被系统定期清理或重启后清空),比如/usr/local/bin/my_once_script.sh,并赋予执行权限:mv /tmp/your_script.sh /usr/local/bin/my_once_script.sh chmod +x /usr/local/bin/my_once_script.sh - 创建systemd服务文件
/etc/systemd/system/run-once.service,内容如下:[Unit] Description=Run initialization script once on first boot After=network.target # 若脚本依赖网络,需添加此配置 [Service] Type=oneshot ExecStart=/usr/local/bin/my_once_script.sh RemainAfterExit=yes # 标记服务已完成,避免重复执行 [Install] WantedBy=multi-user.target - 启用服务:
systemctl enable run-once.service - 原理:启用后系统首次开机进入多用户模式时会执行脚本,
RemainAfterExit=yes让systemd记录服务状态为已完成,后续开机不会重复执行。若需重新触发,执行systemctl reset-failed run-once.service后重启即可。
方案2:rc.local配合标记文件(兼容SysVinit和systemd)
适合所有支持rc.local的系统,实现简单直观:
- 迁移脚本到稳定目录并赋予执行权限(同方案1第一步)。
- 编辑
/etc/rc.local(若文件不存在,先创建并执行chmod +x /etc/rc.local),添加以下内容:#!/bin/bash FLAG_FILE="/var/lib/my_script_executed.flag" SCRIPT_PATH="/usr/local/bin/my_once_script.sh" # 检查标记文件,不存在则执行脚本并创建标记 if [ ! -f "$FLAG_FILE" ]; then "$SCRIPT_PATH" touch "$FLAG_FILE" fi exit 0 - 原理:每次开机rc.local执行时,通过标记文件判断脚本是否已运行过,仅在首次开机时执行。
方案3:inittab(仅针对老式SysVinit系统)
针对仍使用SysVinit的旧版Linux发行版(如CentOS 6及更早版本):
- 迁移脚本到稳定目录并赋予执行权限(同方案1第一步)。
- 编辑
/etc/inittab,添加一行配置:once:3:once:/usr/local/bin/my_once_script.sh - 重新加载inittab配置:
init q - 原理:
once关键字指定该命令仅在系统进入运行级别3(多用户模式)时执行一次,后续开机不会重复运行。
关键注意事项
- 绝对不要保留脚本在
/tmp目录,该目录属于临时文件系统,会被系统自动清理,导致脚本丢失无法执行。 - 若脚本依赖特定服务(如网络、数据库),需在配置中明确执行顺序(如systemd的
After参数、rc.local中添加等待逻辑),避免因依赖未就绪导致执行失败。
内容的提问来源于stack exchange,提问作者raj krish
相关产品推荐
相关产品推荐

