将 IfDefine 与环境变量一起使用

将 IfDefine 与环境变量一起使用

我试图通过使用变量列表并在使用 systemd 插入配置文件启动 Apache 时加载环境变量,使我的配置尽可能灵活且易于配置。由于环境变量在服务器启动后不会改变,因此我想通过使用 Apache 的指令而不是常规指令/etc/sysconfig来提高性能和灵活性。IfDefineIf

常规指令的一个问题<If>... </If>是,块内的指令总是评估即使他们不是执行。如果您使用环境变量作为参数,这一点非常重要,如下所示:

SVNParentPath ${MY_SVN_REPOSITORIES_PATH}

${MY_SVN_REPOSITORIES_PATH}在这种情况下,如果计算结果为空字符串,Apache 将抛出错误并拒绝启动。我想在系统环境变量MY_SVN_REPOSITORIES_PATH为空或未设置时禁用服务存储库。我该怎么做?

答案1

这是一个丑陋的 hack,但它可以工作。我们在这里做的是使用Define指令来定义一个变量,其姓名包括价值环境变量,然后检查该变量是否定义:

Define "Test${MY_SVN_REPOSITORIES_PATH}"
<IfDefine Test>
    # the variable is set to an empty string
</IfDefine>
<IfDefine !Test>
    # SVN repositories are configured or the variable is unset
</IfDefine>
<IfDefine "Test/srv/svn">
    # SVN repositories are configured to be in /srv/svn
</IfDefine>

如果${MY_SVN_REPOSITORIES_PATH}计算结果为空字符串,则将定义配置参数“Test”。如果环境变量计算结果为其他值(如果环境变量未设置,则可能是文字${MY_SVN_REPOSITORIES_PATH}),则不会定义配置参数“Test”(本身)。

这里有一个限制:我们可以测试具体价值,包括一个空字符串,但我们无法仅使用指令来测试变量是否未设置IfDefine。这是因为没有办法将文字美元符号和括号字符放入指令中,IfDefine而不会让 Apache 尝试扩展它们1。如果没有转义字符,您永远不会知道 Apache 是在与文字变量名称进行比较,还是与它的值进行比较。

但是,也有一个丑陋的办法可以解决这个问题!

# Prevent environment variable expansion by splitting the variable name into two literals
Define FirstPartOfVariableName "${MY_SVN_"
Define SecondPartOfVariableName "REPOSITORIES_PATH}"

Define "Test${MY_SVN_REPOSITORIES_PATH}"
<IfDefine "Test">
    # Environment variable is set to an empty string
</IfDefine>
<IfDefine Test${FirstPartOfVariableName}${SecondPartOfVariableName}>
    # Environment variable is not set
</IfDefine>
<IfDefine !Test>
    <IfDefine !Test${FirstPartOfVariableName}${SecondPartOfVariableName}>
        # The environment variable is set, and is not an empty string.
    </IfDefine>
</IfDefine>

在这里,我们绕过了环境变量扩展,以便我们能够识别配置过程中我们关心的三种主要情况。您不能IfDefine使用 OR 运算组合指令,因此“未设置”和“空字符串”只能作为单独的块,但您可以在块之间复制和粘贴配置,也可以签出mod_macro


  1. 我检查了 Apache 的源代码。该函数位于ap_resolve_envcore.c,并且调用它的函数似乎仅在设置了编译时开关时才禁用该调用。

相关内容