이 답변을 기반으로 잠금이 해제되면 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 프로세스가 종료되지 않는다는 것입니다. 스크립트 자체에 두 개의 프로세스가 있고 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