Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

What is the difference between ${var} and %{var} in httpd.conf?

How and when would one use ${} and %{}?

http://httpd.apache.org/docs/2.4/configuring.html mentions :

The values of variables defined with the Define of or shell environment variables can be used in configuration file lines using the syntax ${VAR}.

http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html mentions:

Server-Variables:These are variables of the form %{ NAME_OF_VARIABLE }

and

RewriteMap expansions:These are expansions of the form ${mapname:key|default}.

Will ${VAR} be used everywhere in httpd.conf, except in mod_rewrite directive's (like RewriteCond, RewriteRule but except for RewriteMap expansions which use ${} as in RewriteRule ^/ex/(.*) ${examplemap:$1} )

Would a variable set in httpd.conf using SetEnvIf Directive, for use in same httpd.conf, be used as ${var} except when the variable is used with mod_rewrite directive's, where the variable would be used as %{var}?

share|improve this question
add comment

2 Answers

up vote 3 down vote accepted

What is the difference between ${var} and %{var} in httpd.conf?

Pretty much everything. There's no hard-and-fast rule that says "$ does x, % does y", because they do different things depending on where and how they're used.

Will ${VAR} be used everywhere in httpd.conf, except in mod_rewrite directive's

No - ${VAR} is applied as a replacement in every location throughout the config, even in a mod_rewrite related line. These can only be defined at startup using the -D option passed to the httpd binary, or the Define directive.

This can be done because those variables must not contain a : character, whereas the RewriteMap usage must contain a : character. This allows for the $ to be used in extremely different ways with no conflict - the parser sees the : and knows that it's not supposed to be replacing that.

Would a variable set in httpd.conf using SetEnvIf Directive, for use in same httpd.conf, be used as ${var} except when the variable is used with mod_rewrite directive's, where the variable would be used as %{var}?

No. Environment variables are not the same as variables set via -D or Define - they're a completely separate per-request context (those are the ones you're setting with SetEnvIf), that only certain directives will use. They're specifically mentioned where supported - in mod_rewrite they're %{ENV:variable}, in logs they're %{variable}e, and a lot of directives have a logic check that looks like env=variable.


So, basically; it's a confusing mess - a testament to the web server's history over the past couple decades. Probably the main thing that's confusing you is that mod_rewrite's syntax doesn't extend to any other part of the config in any way; it's all different. The main point to take from all this is that there isn't a governing 'rule' to make all of this make sense - a $ in one spot means something completely different from a $ in another spot.

A few handy reference points:

  1. If you're looking to set a variable statically when Apache starts, use Define and ${VAR} to replace once, on Apache's startup. This is mostly useful for when you want to do something like share config files between a development and production environment - but it's not to be confused with the use of the $ from RewriteMap, which always contains a :.
  2. If you're looking to work with variables in specific requests, then environment variables are what you're after - but you cannot make assumptions about the syntax that you'll use to get at them when used with a specific directive. You'll need to check the documentation for that directive.
  3. When mod_rewrite is in question, throw out everything you thought you knew about variables and their syntax. It has its own set of variables in %{VAR}, you can get at your 'normal' environment variables with %{ENV:VAR}, and you can set environment variables with [E=VAR].
share|improve this answer
    
wow! thanks for such a lengthy write up! It will take me a while to digest this. Quite strange that Apache docs don't document this in one place, this must be quite confusing to lot of newbies. –  108ium Apr 9 '12 at 18:16
    
Yeah - their docs aren't bad for specific concepts, but the 'big picture' stuff like this is much less clear. –  Shane Madden Apr 9 '12 at 18:25
add comment

I have looked at source code of mod_rewrite, and found that notes in comments (do_expand function):

        /* variable lookup */
        else if (*p == '%') {
        ...
        /* map lookup */
        else {     /* *p == '$' */

so it looks, like % are for exact variables, while $ are for lookups in hash tables ("maps"). also, all mod_rewrite expansions are completely independed from core -- whole expansion done in module by itself.

I was thought earlier, but that was wrong:

${} vars are uses environment of project, and evaluated at time of config parse.

%{} vars are uses environment of request, and evaluated at time request parsed. mod_rewrite uses %{} symantic to prevent config-time interpolation made by httpd core.

share|improve this answer
    
Thanks, Could you please include the link to original documentation for this and if possible, link to a tutorial? –  108ium Apr 1 '12 at 15:19
    
I have never seen that in clear text in documentation. That is how i have understand why that was done. And that was wrong :) –  datacompboy Apr 4 '12 at 3:56
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.