Skip to content

Instantly share code, notes, and snippets.

@ephemient
Created October 16, 2015 01:58
Show Gist options
  • Save ephemient/40ee6beba7d687acb938 to your computer and use it in GitHub Desktop.
Save ephemient/40ee6beba7d687acb938 to your computer and use it in GitHub Desktop.
wait-dbus-service
#!/bin/bash
set -e
eval "$(git rev-parse --parseopt -- "$@" <<EOF || echo exit $?
${0##*/} [OPTIONS...] {SERVICE} [TIMEOUT]
Wait for {SERVICE} to be registered on the bus.
--
y,system Connect to system bus
e,session Connect to user bus
a,address= Connect to bus specified by address
EOF
)"
BUS=(--session)
while getopts yea: opt; do
case "${opt}" in
y) BUS=(--system) ;;
e) BUS=(--session) ;;
a) BUS=(--address="${OPTARG}") ;;
esac
done
shift $((OPTIND-1))
SERVICE=$1
DELAY=$2
if [[ -z ${SERVICE} ]]; then
echo "Must provide {SERVICE}" >&2
exit 129
fi
wait_time() {
if [[ -n ${DELAY} ]]; then
sleep "${DELAY}" && echo '(timeout)' >&2
echo -
fi
}
check_name() {
dbus-send "${BUS[@]}" --dest=org.freedesktop.DBus --print-reply --type=method_call / org.freedesktop.DBus.ListNames |
while IFS= read -r line; do
read -r type value <<<${line}
if [[ ${type} = string && ${value} = "\"$(printf %q "${SERVICE}")\"" ]]; then
printf '%s\n' "${line}"
break
fi
done
}
wait_name() {
local connected= signal= args=() values=()
dbus-monitor "${BUS[@]}" --monitor \
"type='signal',sender='org.freedesktop.DBus',path_namespace='/',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0='$(printf %q "${SERVICE}")'" |
while IFS= read -r line; do
if [[ ${line} = signal[[:space:]]* ]]; then
signal=$(expr match "${line}" '.*;[[:space:]]\+member=\([^[:space:]]\+\)')
signal=${signal:-\?} args=() values=()
if [[ ${signal} = NameAcquired && -z ${connected} ]]; then
connected=1
check_name
fi
elif [[ ${line} != [[:space:]]* ]]; then
signal= args=() values=()
elif [[ -n ${signal} ]]; then
read type value <<<${line}
args+=("${line}") values+=("${value}")
fi
if [[ ${signal} = NameOwnerChanged && -n ${args[2]} && ${values[2]} != '""' && ${values[2]} != "''" ]]; then
printf '%s\n' "${args[0]}"
fi
done
}
trap 'kill -TERM -$$' EXIT
while IFS= read -r line; do
if [[ -n ${line} ]]; then
break
fi
done < <(
wait_time &
wait_name
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment