服务文件的 runit 子进程不会在服务停止时被终止

服务文件的 runit 子进程不会在服务停止时被终止

我正在编写一个 runit 服务,根据这个答案在解锁时重新启动 picomhttps://unix.stackexchange.com/a/439492/161514

#!/bin/bash

OBJECT_PATH=/org/freedesktop/login1/session/$XDG_SESSION_ID
BUS_NAME=org.freedesktop.login1
UNLOCK="$OBJECT_PATH: $BUS_NAME.Session.Unlock ()"
MONITOR_COMMAND="gdbus monitor --system --dest $BUS_NAME --object-path $OBJECT_PATH"

log () {
    echo "$(date +'%F %T.%3N') [$$]" "$@"
}

while read -r signal; do
    log $signal
    if [ "$signal" = "$UNLOCK" ]; then
        log "Restaring picom after unlock."
        SVDIR=$XDG_SERVICE_HOME sv restart picom
    fi
done < <(exec $MONITOR_COMMAND)

问题是,当我停止服务时,gdbus 进程不会被终止。我可以猜测这是因为脚本本身有两个进程,然后 gdbus 和服务停止只会停止脚本而不是 gdbus。

我的问题是我可以以某种方式重写此服务来实现我想要的目的,以便停止服务 gdbus 监控也会停止吗?

答案1

经过一番搜索后,我意识到这是一个普遍问题,并非特定于 runit。我可以使用 coproc 将监控作为异步进程运行,并确保在我的主脚本中,如果出现任何术语信号,我将杀死我的子进程。

这是脚本,以防有人感兴趣

#!/usr/bin/env bash

OBJECT_PATH=/org/freedesktop/login1/session/$XDG_SESSION_ID
BUS_NAME=org.freedesktop.login1
UNLOCK="$OBJECT_PATH: $BUS_NAME.Session.Unlock ()"
MONITOR_COMMAND="gdbus monitor --system --dest $BUS_NAME --object-path $OBJECT_PATH"

log () {
    echo "$(date +'%F %T.%3N') [$$]" "$@"
}

cleanup() {
    # kill all processes whose parent is this process
    pkill -P $$
}

for sig in INT QUIT HUP TERM; do
  trap "
    cleanup
    trap - $sig EXIT
    kill -s $sig "'"$$"' "$sig"
done

coproc $MONITOR_COMMAND

while read -r signal <&"${COPROC[0]}"; do
    log $signal
    if [ "$signal" = "$UNLOCK" ]; then
        log "Restaring picom after unlock."
        SVDIR=$XDG_SERVICE_HOME sv restart picom
    fi
done

trap cleanup EXIT

相关内容