As a Unix sysadmin, we experience issues with others (E.g. DBAs) starting/stopping services by interactively running scripts. This means systemd has no knowledge of the state of a service. To prevent this, I insert a conditional in the scripts like this:
# The systemd unit creates a ORACLE_SYSTEMD_UNIT environment variable. If this
# isn't set (i.e. Not running through systemd) then abort.
if [ "${ORACLE_SYSTEMD_UNIT:+set}" == "" ]; then
logmsg "Not initiated through systemd. Aborting"
exit 2
fi
Can anyone suggest a cleaner method, or perhaps an Environment variable that is automatically set by the systemd unit activation?
As pointed out in the comments, you can check the command name of the parent process. In bash the process id of the parent process is stored in $PPID
. The command name for a given pid can be obtained by ps
. This only works if your script is running directly under systemd
.
if [ "$(ps -o comm= $PPID)" != systemd ]; then
echo "Not running under systemd"
fi
If you also want to check the parents of the parents and so on, iterate/recurse. The parent of any pid can be obtained by ps
too.
runsUnderSystemd() {
pid="${1-$$}"
[ "$pid" = 0 ] && return 1
[ "$(ps -o comm= "$pid")" = systemd ] ||
runsUnderSystemd "$(ps -o ppid= "$pid" | tr -d ' ')"
}
if ! runsUnderSystemd; then
echo "Not running under systemd"
fi
With pstree
this can be shortend to
if ! pstree -s $PPID | grep -Fwq systemd; then
echo "Not running under systemd"
fi
Alternatively, you can set an environment variable in your .service
file for systemd ...
[Service]
Environment="STARTED_BY_SYSTEMD=yes"
... which can then be checked in all children of the started service
if [ "$STARTED_BY_SYSTEMD" != yes ]; then
echo "Not running under systemd"
fi
Please note that both approaches are just safeguards against mistakes. An attacker could fake or hide systemd in either way.