在过去的两周里,我一直在为这个问题揪心。我一生都无法弄清楚如何让它发挥作用:
情况
我正在运行带有几个 VirtualBox 虚拟机的 Debian 9 服务器,当服务器因断电重启而关闭时,我想“保存状态”。服务器重新启动后,我希望这些虚拟机再次启动。
保存然后启动虚拟机的脚本运行得非常顺利。那里没问题。启动后启动的部分也很好。问题出在关闭部分。所以我把事情简化了一些。
剩下的问题
我有一个脚本:/home/vorkbaard/goingdown.sh。它向我自己发送一封电子邮件,说明服务器即将关闭。该脚本运行良好。然而,在断电时,它开始执行,但在完成之前因网络中断而中断。
我想要的是是在给出断电或重新启动命令之后但在其他任何事情启动之前执行脚本,例如网络或文件系统关闭。该过程需要等待脚本成功完成。
我试过使用 Systemd 和 SysV,但是虽然我对 SysV 非常熟悉,但它不再让我选择自己的执行顺序,我猜是因为 Systemd 正在取代 is,无论如何我想完全切换到 Systemd,因为 SysV 正在 Debian 中被淘汰。我想继续使用 Debian,而不是切换到 Devuan 或 RHEL。
我知道创建单元文件并将它们移动到正确的位置是正确的方法,但正如我所说 - 我一生都无法找出执行此操作的正确方法。有无数的例子,但似乎没有一个适合我的情况。
实际问题
我应该创建哪些单元文件,将它们放在哪里以及如何告诉我的服务器在重新启动或关闭电源后先运行它们?
也尝试去适应在关机和重新启动之前执行简单的脚本:
在 /etc/systemd/system/test.service 中:
[Unit]
Description=Send an email on shutdown and reboot
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash (also tried with /bin/true)
ExecStop=/root/rebootscript (also tried ExecStop=sh /root/rebootscript. Then the script does nothing on reboot.)
[Install]
WantedBy=multi-user.target
然后重新启动,做了systemctl status test.service
,它说active (exited)
。然而,重新启动时会出现一条消息A stop job is running for Send an e...utdown and reb oot (34s / 1min 30s)_
,提示 1.5 分钟后超时,不会发送任何邮件,服务器会重新启动。
/var/log/syslog
说:
Stopping Send an email on shutdown and reboot...
Creating SSL connection to host
SSL connection using RSA_AES_128_CBC_SHA1
Sent mail for [my email address here] (221. 2.0.0 closing connection q45sm79107etc.53 - gsmtp) uid=0 username=root outbytes=509
Stopped Send an email on shutdown and reboot
但邮件未发送,邮件队列中也没有邮件。我发送邮件的帐户中也没有出现错误。同样,手动运行时脚本工作正常。
在/root/rebootscript
是:
/bin/bash
NOW=$(/bin/date +"%H:%M")
/bin/echo "Rebooting $NOW" | /usr/bin/mailx -s "Rebooting $NOW" [my email address here]
有趣的是,如果我这样做,systemctl stop test.service
我会收到一封邮件,说服务器正在重新启动,因此服务本身似乎可以正常工作。
答案1
好吧,我明白了。我最初发布的脚本没问题,但它是在网络故障后执行的,这解释了为什么邮件没有发送。
细节:https://serverfault.com/questions/785127/how-to-stop-systemd-services-in-specific-order
使它工作的脚本:
[Unit]
Description=Send an email on shutdown and reboot
Wants=network-online.target <---- ADDED THIS
After=network-online.target <----/
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash (also tried with /bin/true)
ExecStop=/root/rebootscript (also tried ExecStop=sh /root/rebootscript. Then the script does nothing on reboot.)
[Install]
WantedBy=multi-user.target
上面的文件可能太多了,但这绝对有效。
谢谢你们 :)