【发布时间】:2022-09-30 18:10:50
【问题描述】:
我正在 bash 中创建一个脚本来执行以下用例,
- 根据名称上的特定单词查找特定服务
- 停止这些服务按特定顺序,例如:service_1、service_2 等等
- 检查这些服务是否已停止并如果有一个仍在运行,它会打印出它的名字
这是我的进步, 首先,我根据一些仅以其名称存在的单词找到了服务,如下所示,
service_1=$(ls /etc/systemd/system | grep -e text1 | awk -F \' \' \'{print $1}\')
service_2=$(ls /etc/systemd/system | grep -e text2 | awk -F \' \' \'{print $1}\')
service_3=$(ls /etc/systemd/system | grep -e text3 | awk -F \' \' \'{print $1}\')
然后,我按照我想要的顺序停止了它们,如下所示:
if [ ! -z \"$service_1\" ] //if service exists
then
systemctl stop $service_1
else
:
fi
if [ ! -z \"$service_2\" ] //if service exists
then
systemctl stop $service_2
else
:
fi
if [ ! -z \"$service_3\" ] //if service exists
then
systemctl stop $service_3
else
:
fi
问题来了。如您所知,停止服务时,可能需要一些时间才能完全停止,因此根据上述条件,它将继续停止第二个服务而不完全停止前一个服务。我想要的是按顺序停止服务,因此在停止第二个服务之前,应该完全停止第一个服务,依此类推。如何做到这一点?我认为这可以通过循环来完成,但我错过了方式。 关于第三个用例,在过滤服务的状态输出作为服务已停止的指示符后,我定义了以下包含单词“inactive”的变量:
service_1_status=$(systemctl status $service_1 | grep -e \"inactive\")
service_2_status=$(systemctl status $service_2 | grep -e \"inactive\")
service_3_status=$(systemctl status $service_3 | grep -e \"inactive\")
然后,我尝试在它们上循环以找出是否有仍然处于活动状态的服务来打印它的名称,如下所示:
arr=($service_1_status $service_2_status $service_3_status $service_q_inf_status)
for i in \"${arr[@]}\"
do
if \"${arr[$i}\" != \"inactive\"
then
echo $i
else
echo \"All Services are now Stopped\"
fi
done
我不知道这种语法是否完全可操作,因为它不起作用,但这是我想要做的逻辑。这样做的正确方法是什么?
-
grep | awk是一种反模式。而不是grep -e text1 | awk -F \' \' \'{print $1}\',只需使用awk \'/text1/{print $1}\' -
Parsing the output of
ls是一种反模式。而不是ls /etc/systemd/system | grep -e text1,只需使用ls /etc/systemd/system/*text1*。这仍然会让您将ls输出通过管道传输到 awk,尽管这仍然是一种反模式 - 向我们展示/etc/systemd/system目录的一些示例内容,以便我们可以帮助您做任何您想做的事情正确的路。 -
您可以使用
systemctl is-active了解服务器是启动还是关闭。--wait将等待停止完成后再继续。查看手册页以了解--wait上的警告。 -
感谢@WilliamPursell 的投入,它确实节省了很多精力。
-
感谢@Nic3500,我还发现了一些有用的选项,可以管理启动/停止服务的顺序,例如 --after 和 --before。