我正在设置我的 Linux 盒子(连接到 UPS),以便在关闭之前正常关闭我的 pfsense 路由器。我正在运行 Ubuntu 16.04,并使用 systemd 来完成此任务。我已经配置了 systemd 服务,并且它可以工作。但是,它在关闭和重新启动时启动脚本。这不好,因为每当我重新启动我的 Linux 机器时,我都会关闭我的路由器。如何更改我的 systemd 服务,使其仅在关机期间激活?
我的设置如下:
[Unit]
Description=PFSense Shutdown script
After=poweroff.target
[Service]
Type=oneshot
ExecStart=/bin/true
ExecStop=/path/to/script/pfsenseshutdown.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
并且,作为参考,pfenseshutdown.sh 脚本相当简单:
#!/bin/bash
ssh [email protected] -i "sudo /etc/rc.halt"
任何帮助将不胜感激。
答案1
以下方法似乎仅在关机时运行脚本,而不是在重新启动时运行脚本。您可以systemd-poweroff.service
按如下方式编辑该文件:
sudo systemctl edit --full systemd-poweroff.service
在该[Service]
部分中,您可以添加一行ExecStartPre
:
ExecStartPre=/path/to/script/pfsenseshutdown.sh
这样,如果您使用然而关闭系统,该脚本将不会被执行halt
。要处理这种情况,您可以将同一行添加到systemd-halt.service
.
请注意,在这种方法中,不使用问题中显示的配置文件。
编辑:先前方法的一个可能的缺点是要执行的脚本包含一个ssh
命令,该命令可能在关闭系统之前无法正常工作(systemd 可能已经停止了必要的网络服务)。下面的方法试图避免这种情况。
对于这个解决方案,我创建了一个pfsenseshutdown.service
包含以下内容的单元
[Unit]
Description=PFSense Shutdown script
DefaultDedendencies=no
[Service]
Type=oneshot
ExecStart=/usr/bin/touch /dev/shm/shuttingdown
[Install]
WantedBy=systemd-halt.service systemd-poweroff.service
当启动关机程序时,这个文件似乎会导致该ExecStart
行立即执行,导致该文件/dev/shm/shuttingdown
存在(该/dev/shm
目录是内存文件系统,因此重新启动后会被清除)。
现在,为了确保您的脚本在网络完全取消初始化之前执行,我运行了
systemctl edit --full networking.service
ExecStop
最初,它在我的 ubuntu 16.04 虚拟机上包含以下行:
ExecStop=/sbin/ifdown -a --read-environment
此行已替换为首先运行脚本的版本,在此示例中:
ExecStop=/path/to/script/pfsenseshutdown.sh && /sbin/ifdown -a --read-environment
然后,该pfsenseshutdown.sh
脚本测试文件是否/dev/shm
存在,并相应地执行 ssh 命令。我还添加了一个小sleep
命令:systemd 并行执行许多操作,这希望有助于防止测试因文件不存在而失败然而。
#!/bin/bash
sleep 1
if [ -e /dev/shm/shuttingdown ] ; then
# Your ssh command here
fi