我如何在使用systemd关机之前运行脚本?


17

注意:简短说明的问题可以在底部找到。

我有一个脚本,可将文件备份到外部USB驱动器上。执行该过程可能需要一段时间,具体取决于我创建的新数据量。我想在系统每次关闭时自动运行它。

我正在使用最新更新的Fedora 23(systemd)。

我试图通过多种方式实现这一目标,但是我无法使其正常工作。

StopExec的长期运行过程

autobackup.service:

[Unit]
Description=Slow backup script
Requires=local-fs.target

[Service]
ExecStart=/bin/true
ExecStop=/etc/systemd/system/do_backup.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multiuser.target

我使用激活了它,systemctl enable autobackup.service然后从开始了systemctl start autobackup.service

我的启动日志(journalctl -b-1)的一部分:

Dez 22 17:45:27 localhost systemd[1]: Unmounted /mnt/BACKUP.
Dez 22 17:45:27 localhost do_backup.sh[4296]: At subvol /home/BACKUP.2015_12_22-17_45_25
Dez 22 17:45:27 localhost do_backup.sh[4296]: ERROR: parent subvol is not reachable from inside the root subvol.
Dez 22 17:45:27 localhost do_backup.sh[4296]: At snapshot BACKUP.2015_12_22-17_45_25
Dez 22 17:45:27 localhost do_backup.sh[4296]: ERROR: failed to dump stream. Broken pipe
Dez 22 17:45:27 localhost systemd[1]: autobackup.service: Control process exited, code=exited status=1
Dez 22 17:45:27 localhost systemd[1]: Stopped Slow backup script.
Dez 22 17:45:27 localhost systemd[1]: autobackup.service: Unit entered failed state.

请注意,我没有缩短这两者之间的任何时间,它确实在脚本开始之前就卸载了/ mnt / BACKUP,这很有趣。

关闭之前

autobackup.service:

[Unit]
Description=Slow backup script
DefaultDependencies=no
Before=shutdown.target

[Service]
ExecStart=/etc/systemd/system/do_backup.sh
Type=oneshot

systemctl edit shutdown.target

[Unit]
Requires=autobackup.service

输出基本相同。

问题

我认为问题在于,在两种情况下,systemd都会与所有其他关闭脚本并行地启动我的脚本,这将卸载BACKUP并停用管道基础结构(当卸载速度不够快时,我有时会收到另一个错误)。

问题

我该如何教导systemd在关闭时首先启动我的脚本,等到它退出后再启动其余的关闭脚本/目标/单元/任何东西?

Answers:


12

无需创建或编辑服务文件。只需将脚本放入

/usr/lib/systemd/system-shutdown/

https://www.freedesktop.org/software/systemd/man/systemd-halt.service.html

在执行实际的系统暂停/电源关闭/重新启动/ kexec之前,systemd-shutdown将立即在/ usr / lib / systemd / system-shutdown /中运行所有可执行文件,并将一个参数传递给它们:“ halt”,“ poweroff”,“ reboot” ”或“ kexec”,具体取决于所选的操作。此目录中的所有可执行文件都并行执行,并且在所有可执行文件完成之前不会继续执行操作。

我只是用它来嘟嘟PC扬声器。


2
您是否必须建立此目录?我在Ubuntu 16.04和Raspbian(jessie)上都没有它-两者都是基于systemd的。
WoJ

2
Debian系统使用不同的路径/lib/systemd/system-shutdown/。另外请注意,在文件系统已经以只读方式挂载之后,这些脚本在关闭时执行得非常晚。因此,除非重新安装为读写(mount -oremount,rw /),否则对文件系统的任何写访问都将失败。请参阅如何在重新引导或关闭时在/ usr / lib / systemd / system-shutdown /中执行脚本?
Frank Breitling

9
OP要求关闭时“在其他所有操作之前”执行脚本。系统关闭脚本将在杀死内核之前立即执行所有其他操作。
格雷格·亚历山大

11

我知道了!

使用StopExec进行长期运行的解决方案,并按如下所示进行修改:

autobackup.service:

[Unit]
Description=Slow backup script
RequiresMountsFor=/mnt/BACKUP /home

[Service]
ExecStop=/etc/systemd/system/do_backup.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

请注意以下行:

RequiresMountsFor=/mnt/BACKUP /home

这样可以正常工作。


2
您无需执行systemctl editsystemctl enable autobackup具有相同的效果,并且更惯用,并且应该起作用,因为您[Install]的单元中已经有该部分。不过,您将必须在目标名称中更正该错字。;)
Stefan Majewsky '16

OMG,我一直在寻找解决方案,以在卸载任何驱动器之前调用备份脚本。谢谢!
deanresin

2
这对我不起作用。我没有任何坐骑,我只是想确保我的脚本在其他单元关闭之前运行。
2rs2ts
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.