测试bash脚本是否从systemd启动

问题描述 投票:0回答:1

作为Unix系统管理员,我们通过交互运行脚本来与其他人(例如DBA)启动/停止服务时遇到问题。这意味着systemd不了解服务状态。为了防止这种情况,我在这样的脚本中插入一个条件语句:

# 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

有人可以建议更干净的方法,或者是由systemd单元激活自动设置的Environment变量吗?

bash systemd
1个回答
1
投票

如注释中所指出,您可以检查父进程的命令名称。在bash中,父进程的进程ID存储在$PPID中。给定pid的命令名称可以通过ps获得。仅当您的脚本在systemd下运行直接时,此方法才有效。

if [ "$(ps -o comm= $PPID)" != systemd ]; then
    echo "Not running under systemd"
fi

如果您还想检查父母的父母等等,请重复/递归。任何pid的父对象也可以通过ps获得。

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

使用pstree,可以缩短为

if ! pstree -s $PPID | grep -Fwq systemd; then
    echo "Not running under systemd"
fi

或者,您可以在.service文件中为systemd设置环境变量...

[Service]
Environment="STARTED_BY_SYSTEMD=yes"

...然后可以在已启动服务的所有子级中检查

if [ "$STARTED_BY_SYSTEMD" != yes ]; then
   echo "Not running under systemd"
fi

请注意,这两种方法都只是防止错误的保障。攻击者可以通过两种方式伪造或隐藏systemd。

© www.soinside.com 2019 - 2024. All rights reserved.