我有 Centos 7+ 系统,它们都使用 systemd。有时,在进行重要的系统更改后,最好的处理方式是重新启动每个当前正在运行的服务。如果我一次重新启动一个服务,那么系统通常会保持在线,并且很容易看到出现的服务问题。所以我破解了这个小 bash 脚本,它可以重新启动每个正在运行的 systemd 服务,除了某些命名服务,我认为这是保持机器在线的核心。
#!/bin/bash
set -e
set -u
running=$(systemctl list-units --type service | grep running \
| grep -iv audit \
| grep -iv disk \
| grep -iv drive \
| grep -iv getty \
| grep -iv irq \
| grep -iv libstoragemgt \
| grep -iv lvm \
| grep -iv multipath \
| grep -iv polkit \
| grep -iv storage \
| cut -d' ' -f1)
for service in $running ; do
echo "$service"
systemctl restart "$service"
done
我希望有以下几点可以改进:
- 对“正在运行”进行 grepping 是一种粗暴的过滤正在运行的任务的方法,而且多个管道非常昂贵。
- 使用
cut
确实很脆弱,并且当 systemd 的输出格式改变时就会中断。 systemctl restart
在启动失败时不设置返回代码,因此即使服务无法停止或启动,脚本仍会继续运行。
有哪些更好的方法可以实现这一点?
答案1
为了改进你的代码,你可以执行以下操作:
- 使用 systemctl
--state running
而不是grep running
来过滤您需要的服务。 - 使用
grep -v -f exclude-services.list
而不是一连串grep
的 - 一次性使用
systemctl try-restart s1 s2 s3 ...
所有内容,而不是循环遍历列表。
首先列出要排除的服务exclude-services.list
:
potom@vm /tmp $ cat exclude-services.list
audit.service
disk.service
drive.service
getty.service
irq.service
libstoragemgt.service
lvm.service
multipath.service
polkit.service
storage.service
然后这个脚本就可以工作了:
potom@vm /tmp $ cat restart-all.sh
RESTART_SERVICES=$(systemctl list-units --type service --state running | \
awk '$1 ~ /\.service/{print $1}' | \
grep -v -f exclude-services.list )
systemctl try-restart ${RESTART_SERVICES}
这可能比你的脚本更强大一些。让我知道进展如何。
答案2
有哪些更好的方法可以做到这一点?
重新启动服务器:)
重新启动所有服务通常不是一个好主意。要么你正在更新整个系统,然后你想确保一切都使用最新的修补库。要么你正在更新/重新配置一个服务,那么简单的操作systemctl reload whatever.service
就足够了,无需重新启动所有正在运行的服务。
此外,最好时不时地重启服务器,以确保它确实是可重启。我见过运行多年的服务器,但没人敢重启,因为没人知道它们是否真的能恢复,做了哪些更改但未保存,等等。
如果它是一个临界系统它肯定位于某个高可用性集群中,重新启动一个节点无关紧要。如果不是一个关键系统您可以重新启动它,即使是在下班时间之后或周末。
因此,回答你的问题 -重启服务器