この回答に基づいてロックが解除されると、Picomを再起動する runit サービスを作成しています。https://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プロセスが終了しないことです。スクリプト自体には2つのプロセスがあり、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