测试 bash 脚本是否从 systemd 启动
Test if bash script was initiated from systemd
作为 Unix 系统管理员,我们通过交互式 运行 脚本遇到其他人(例如 DBA)starting/stopping 服务的问题。这意味着 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 单元激活自动设置的环境变量吗?
正如评论中指出的,您可以检查parent进程的命令名称。在 bash 中,parent 进程的进程 ID 存储在 $PPID
中。给定 pid 的命令名称可以通过 ps
获得。这仅在您的脚本 运行 直接 在 systemd
.
下有效
if [ "$(ps -o comm= $PPID)" != systemd ]; then
echo "Not running under systemd"
fi
如果您还想检查 parent 的 parent 等等,iterate/recurse。任何pid的parent也可以通过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"
... 然后可以在启动服务的所有 children 中检查
if [ "$STARTED_BY_SYSTEMD" != yes ]; then
echo "Not running under systemd"
fi
请注意,这两种方法都只是为了防止错误。攻击者可以通过任何一种方式伪造或隐藏 systemd。
作为 Unix 系统管理员,我们通过交互式 运行 脚本遇到其他人(例如 DBA)starting/stopping 服务的问题。这意味着 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 单元激活自动设置的环境变量吗?
正如评论中指出的,您可以检查parent进程的命令名称。在 bash 中,parent 进程的进程 ID 存储在 $PPID
中。给定 pid 的命令名称可以通过 ps
获得。这仅在您的脚本 运行 直接 在 systemd
.
if [ "$(ps -o comm= $PPID)" != systemd ]; then
echo "Not running under systemd"
fi
如果您还想检查 parent 的 parent 等等,iterate/recurse。任何pid的parent也可以通过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"
... 然后可以在启动服务的所有 children 中检查
if [ "$STARTED_BY_SYSTEMD" != yes ]; then
echo "Not running under systemd"
fi
请注意,这两种方法都只是为了防止错误。攻击者可以通过任何一种方式伪造或隐藏 systemd。