Ubuntu 22.04中如何在关机时于网络(含域名解析)可用状态下运行脚本
我来帮你搞定这个关机时保留网络和域名解析的问题,你遇到的域名解析失效确实是Ubuntu 22.04里systemd关机流程的常见小坑——核心问题是关机时systemd会按依赖顺序停止服务,默认情况下DNS和网络服务可能比你的脚本先停,导致域名解析失效。
下面给你两种靠谱的解决方法,优先推荐systemd的标准配置,毕竟是Ubuntu现在的主流管理方式:
方法一:正确配置systemd服务文件
你之前的配置方向有点反了——关机时的依赖逻辑和启动时是反过来的:After=是启动时让你的服务在某个目标之后启动,但关机时我们需要让脚本在网络、DNS服务停止之前运行,所以要用Before=来指定这些要被停止的目标。
1. 创建服务文件
在/etc/systemd/system/目录下新建一个服务文件,比如shutdown-task.service:
sudo nano /etc/systemd/system/shutdown-task.service
2. 写入配置内容
把下面的内容粘贴进去,注意替换/path/to/your/script.sh为你实际的脚本路径:
[Unit] Description=Run custom script with network and DNS available on shutdown DefaultDependencies=no # 关键:脱离默认关机依赖链,避免被提前终止 Before=shutdown.target network.target nss-lookup.target # 脚本在这些目标停止前运行 Requires=network.target nss-lookup.target # 确保网络和DNS服务在脚本运行时仍活跃 [Service] Type=oneshot ExecStart=/path/to/your/script.sh RemainAfterExit=true # 告诉systemd服务已启动,关机时触发执行 TimeoutStartSec=0 # 关闭启动超时,避免脚本被强制终止 [Install] WantedBy=multi-user.target
3. 启用并测试服务
保存文件后,执行以下命令启用服务:
sudo systemctl daemon-reload sudo systemctl enable shutdown-task.service
测试小技巧:别直接关机测试,可以先手动启动服务验证脚本功能(包括域名解析):
sudo systemctl start shutdown-task.service
然后查看脚本是否正常执行,比如检查脚本的输出日志或者远程服务的记录。
方法二:用SysVinit遗留目录(备选方案)
如果systemd的配置还是有问题,可以试试传统的rc0.d目录方法——这是SysVinit时代的残留机制,但Ubuntu 22.04依然兼容:
1. 准备脚本
确保你的脚本有可执行权限:
chmod +x /path/to/your/script.sh
2. 创建软链接到rc0.d目录
关机对应的运行级别是rc0.d,我们需要创建一个以S开头的链接(S表示Start,关机时会按数字从小到大执行这些脚本),数字越小,脚本越先执行(这样能抢在网络服务停止前运行):
sudo ln -s /path/to/your/script.sh /etc/rc0.d/S01shutdown-script
3. 测试
同样可以手动运行脚本验证功能,关机时系统会自动执行这个链接指向的脚本。
额外调试小贴士
如果还是遇到域名解析问题,可以在脚本里加日志排查:
# 在脚本开头添加日志输出 echo "Shutdown script started at $(date)" >> /var/log/shutdown-script.log # 测试域名解析并记录结果 nslookup your-remote-host.com >> /var/log/shutdown-script.log 2>&1
关机后查看/var/log/shutdown-script.log,就能知道域名解析失败的具体原因。
备注:内容来源于stack exchange,提问作者Adam Jacobs

