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

sid*_*com 79 linux shutdown systemd

我需要在该[install]部分中添加什么,以便 systemd/home/me/so.pl在关机之前和/proc/self/net/dev被销毁之前运行?

[Unit]
Description=Log Traffic

[Service]
ExecStart=/home/me/so.pl

[Install]
?
Run Code Online (Sandbox Code Playgroud)

小智 90

建议的解决方案是将服务单元作为正常服务运行 - 查看[Install]部分。所以一切都必须逆向思考,依赖也是如此。因为关机顺序是反向启动顺序。这就是为什么脚本必须放在ExecStop=.

以下解决方案对我有用:

[Unit]
Description=...

[Service]
Type=oneshot
RemainAfterExit=true
ExecStop=<your script/program>

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

RemainAfterExit=true当你没有ExecStart动作时需要它。

创建文件后,请确保systemctl daemon-reloadsystemctl enable yourservice --now

我刚从 systemd IRC 得到它,学分将归于 mezcalero。

  • 在 ubuntu 16.04 你必须有一个 `ExecStart=/bin/true`。 (9认同)
  • 当没有 `ExecStart` 时,我对 _WHY_ `RemainAfterExit=true` 的假设是必需的,因为如果它认为服务没有运行,`systemd` 将不会尝试运行 `ExecStop`。`RemainAfterExit=true` 导致 `systemd` _相信_服务正在运行,从而导致它在关闭时运行 `ExecStop`。 (4认同)
  • @2rs2ts,你能更具体地澄清“不起作用”吗?服务未加载?它的“ExecStop”是否开始执行但在进程完成之前被杀死?还有别的事吗? (2认同)

Pio*_*icz 11

  • 在启动任何重启/关闭/停止/kexec 服务之前(即在根文件系统重新挂载为只读之前的最后一刻)运行服务,请使用以下服务配置:

    [Unit]
    Description=Save system clock on shutdown
    DefaultDependencies=no
    After=final.target
    
    [Service]
    Type=oneshot
    ExecStart=/usr/lib/systemd/scripts/fake-hwclock.sh save
    
    [Install]
    WantedBy=final.target
    
    Run Code Online (Sandbox Code Playgroud)

    启用它:

    systemctl enable my_service.service
    
    Run Code Online (Sandbox Code Playgroud)
  • 在实际重新启动/关闭/停止/kexec之前运行脚本(当您无法写入根文件系统时,因为它以只读方式重新安装)将此脚本可执行文件添加到/usr/lib/systemd/system-shutdown目录中。

    在执行实际系统halt/poweroff/reboot/kexec systemd-shutdown 之前,将运行/usr/lib/systemd/system-shutdown/ 中的所有可执行文件,并向它们传递一个参数:“halt”、“poweroff”、“rebo​​ot” " 或 "kexec",取决于选择的操作。此目录中的所有可执行文件都是并行执行的,并且在所有可执行文件完成之前不会继续执行操作。

另见:

https://www.freedesktop.org/software/systemd/man/bootup.html

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

  • 我想在启动重新启动后尽可能接近执行一些操作,在 `final.target` 之前。理想情况下,我希望它是用户执行 `$ sudo reboot` 后执行的第一件事。 (7认同)

sid*_*com 8

据我所知,这满足了我的需要(但我不知道确切原因)。

[Unit]
Description=Log Traffic
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target


[Service]
ExecStart=/usr/local/bin/perl /home/me/log_traffic.pl --stop
Type=oneshot
Run Code Online (Sandbox Code Playgroud)

  • 我不知道这将如何工作,除非您还将“WantedBy=shutdown.target restart.targethalt.target”添加到“[Unit]”部分。`Before=` 和 `After=` 不会改变依赖关系。 (4认同)
  • 它碰巧工作是因为两件事:1) DefaultDependencies=no 使它忽略所有依赖项并在开始时“首先”运行,在停止时“最后”运行,始终尊重“之前”和“之后”子句。2)它恰好有一个关于关闭/重启/停止目标的 Before 子句,所以它会在停止时到达关闭/重启/停止之前运行(因为它们只在停止时运行,它恰好可以做你想做的事)。 (3认同)

Ulr*_*gel 6

我不完全确定,但我认为您不需要安装部分,尽管我明确添加了它。我也没有测试它,但我认为它应该可以帮助你开始:

[Unit]
Description=Log Traffic
Requires=network.target
After=network.target
Before=shutdown.target
DefaultDependencies=no

[Service]
ExecStart=/home/me/so.pl
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=shutdown.target
Run Code Online (Sandbox Code Playgroud)