如何使用 Systemd 创建一个简单的看门狗?

如何使用 Systemd 创建一个简单的看门狗?

我有一个简单的脚本,用于检查某些长时间运行的进程(即永远)是否正在运行,如果没有,则重新启动它们(省略了一些细节):

#!/bin/bash

PROC_LIST=$(ps ax | grep <stuff>)

while read cfg
do
  PROC_NAME=$(echo $cam_cfg | cut -f2 -d' ')
  PROC_COUNT=$(echo $PROC_LIST | tr ' ' '\n' | grep $PROC_NAME | wc -l)
  if [[ $PROC_COUNT -eq 0 ]]; then
    echo "Starting process for $PROC_NAME"
    <process start> 2> /dev/null &
  fi
done < $CONFIG

这里的想法是获取相关进程的列表,并查看它们是否包含配置文件中指定的关键字。我怀疑重要的一点是,如果需要的话,我会使用 & 来分叉该进程。如果我手动运行该脚本,它就会起作用。

我希望 Systemd 每 30 秒运行一次这个脚本。为此,我创建了以下单元:

服务:

[Unit]
Description=Check processes

[Service]
Type=oneshot
WorkingDirectory=/home/user/scripts
ExecStart=/home/user/scripts/watchdog.sh /config
User=user

[Install]
WantedBy=multi-user.target

定时器:

[Unit]
Description=Check running processes

[Timer]
OnBootSec=30s
OnActiveSec=30s

[Install]
WantedBy=timers.target

当使用 Type=oneshot 时,我发现监视的进程根本没有启动,因此计时器每隔 30 秒就会启动并尝试再次启动所有进程。我怀疑这是因为我正在分叉,因此当服务结束时,所有子进程也会结束。

当我使用 Type=forking 时,我看到进程启动并按要求保持。然而,在这种情况下,计时器永远不会被调度,因此永远不会再次运行。我怀疑这是因为它没有意识到分叉服务需要重新激活。所以:

  1. 如何解决上述问题,以便无论发生什么情况,脚本每 30 秒运行一次?
  2. 这个练习让我觉得我实际上是在对抗 systemd。有没有更好的设计呢? CONFIG 是一个任意且可能是动态的列表,因此我有点不愿意为每个条目创建一个 systemd 服务。

相关内容