Skip to content

Instantly share code, notes, and snippets.

@PhrozenByte
Created November 26, 2021 21:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PhrozenByte/d796ce6f9db2300fd502d88c13582262 to your computer and use it in GitHub Desktop.
Save PhrozenByte/d796ce6f9db2300fd502d88c13582262 to your computer and use it in GitHub Desktop.
Waits until a systemd system or user unit is active.
#!/bin/bash
# systemd-wait-unit-active.sh
# Waits until a systemd system or user unit is active.
#
# Notice: When using this script with user units you must ensure that `sudo`
# can call `systemctl` proberly. This often fails due to `systemctl` not
# finding the user's D-Bus socket. Ensure that the user runs a D-Bus daemon
# and that the '$XDG_RUNTIME_DIR' environment variable is defined.
#
# Copyright (C) 2021 Daniel Rudolf (<https://www.daniel-rudolf.de>)
# License: The MIT License <http://opensource.org/licenses/MIT>
#
# SPDX-License-Identifier: MIT
set -eu -o pipefail
print_usage() {
echo "Usage:"
echo " $(basename "$0") [--quiet] [--timeout SEC] [--user USER] SYSTEMD_UNIT"
}
UNIT=
QUIET=
TIMEOUT=30
USER=
while [ $# -gt 0 ]; do
if [ "$1" == "--quiet" ] || [ "$1" == "-q" ]; then
QUIET=1
shift
elif [ "$1" == "--timeout" ] || [ "$1" == "-t" ]; then
if [ $# -lt 2 ]; then
print_usage >&2
exit 1
elif ! [[ "$2" =~ ^[0-9]+$ ]]; then
echo "Invalid timeout '$2'" >&2
exit 1
fi
TIMEOUT="$2"
shift 2
elif [ "$1" == "--user" ] || [ "$1" == "-u" ]; then
if [ $# -lt 2 ]; then
print_usage >&2
exit 1
elif ! id -u "$2" > /dev/null 2>&1; then
echo "Invalid user '$2'" >&2
exit 1
fi
USER="$2"
shift 2
elif [ -z "$UNIT" ]; then
UNIT="$1"
shift
else
print_usage >&2
exit 1
fi
done
if [ -z "$UNIT" ]; then
print_usage >&2
exit 1
fi
if [ -z "$USER" ]; then
UNIT_INFO="system unit '$UNIT'"
__systemctl() {
systemctl --full --no-legend --no-pager --plain --system "$@" 2> /dev/null
}
else
UNIT_INFO="user unit '$UNIT' of '$USER'"
__systemctl() {
sudo --non-interactive --login --user "$USER" -- \
systemctl --full --no-legend --no-pager --plain --user "$@" 2> /dev/null
}
fi
if [ -z "$(__systemctl list-unit-files "$UNIT" ; __systemctl list-units --all "$UNIT")" ]; then
echo "Unknown $UNIT_INFO" >&2
exit 1
fi
[ -n "$QUIET" ] || echo -n "Waiting for $UNIT_INFO to start"
for (( ; TIMEOUT > 0 ; TIMEOUT-- )); do
if __systemctl is-active --quiet "$UNIT"; then
[ -n "$QUIET" ] || echo " [success]"
exit 0
fi
[ -n "$QUIET" ] || echo -n "."
sleep 1
done
[ -n "$QUIET" ] || echo " [timeout]"
exit 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment