推荐使用 systemd 服务单元(.service)配合 type=oneshot 管理 linux 中一次性脚本,因其支持依赖控制、日志记录、失败重试和环境隔离;需创建 service 文件,设 type=oneshot、execstart 指向脚本,并通过 systemctl start 手动触发或搭配 timer/ systemd-run 实现定时或事件触发。

在 Linux 中,用 systemd 管理一次性、非常驻(即执行完就退出)的脚本,推荐使用 systemd 服务单元(.service)配合 Type=oneshot。它专为这类短时任务设计,支持依赖控制、日志记录、失败重试、环境隔离等能力,比直接写 shell 脚本或 cron 更可靠可控。
创建一个 oneshot 类型的服务单元
新建服务文件,例如 /etc/systemd/system/backup-once.service:
[Unit]
Description=Run backup script once
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/perform-backup.sh
RemainAfterExit=no
User=backupuser
Environment="PATH=/usr/bin:/bin"
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
关键点说明:
yuanfang-skills 的共享设计系统,提供 token CSS 变量、12+ 主题以及可复用的布局类型 HTML 块,供 yuanfang-html-image(以及 fu...)使用。
-
Type=oneshot表示服务启动后等待ExecStart进程退出才视为完成;默认不保持运行 -
RemainAfterExit=no(默认值)表示进程退出后服务状态立即变为inactive;若设为yes,则退出后仍显示为active (exited),适用于需标记“已执行过”的场景 -
User=和Environment=可确保脚本在干净、受限的上下文中运行 -
StandardOutput/Error=journal保证输出自动进 journal,可用journalctl -u backup-once查看
手动触发执行
启用并立即运行一次(不设开机自启):
-
sudo systemctl daemon-reload(每次修改服务文件后必须执行) -
sudo systemctl start backup-once.service(触发执行) -
sudo systemctl status backup-once.service查看结果和退出码 - 执行完即停止,
is-active backup-once返回inactive
按需或定时触发(非常驻)
如果希望定期或响应事件执行,但每次仍是独立的一次性任务,可组合使用:
-
定时执行:配一个
.timer单元(如backup-once.timer),启用 timer 即可,服务本身仍为 oneshot,每次触发都新建实例 -
事件触发:用
systemd-run临时提交一次任务,适合脚本化调用:systemd-run --scope --on-active=10s /usr/local/bin/notify.sh(10 秒后执行)
或更轻量:systemd-run --no-block --on-unit-active-of=nginx.service /bin/sh -c 'echo "nginx reloaded" | logger' -
条件执行:在
[Service]中加ConditionPathExists=/tmp/do-backup,避免无条件运行
调试与排错要点
常见问题及应对方式:
- 脚本不执行?检查
systemctl status输出中的ExecStart行是否报权限/路径错误;确认脚本有可执行权限(chmod +x) - 环境变量缺失?不要依赖 shell 的
~/.bashrc,显式通过Environment=或EnvironmentFile=注入 - 需要等脚本完全结束再做后续操作?在依赖它的服务中用
After=backup-once.service并确保其成功退出(WantedBy=不代表等待,After+顺序 +Requires=才构成强依赖) - 想查看详细日志?用
journalctl -u backup-once --since "2 hours ago" -o short-precise










