In my ~/.Xresources file, I'd like to include another file whose location is dependent on the value of an environment variable. Is this possible?

#include "${env_path}/abc/def/Xresources"

does not seem to expand ${env_path}.

  • IMO not possible. What's the purpose anyway? – jirib Feb 26 '17 at 12:31
up vote 4 down vote accepted

Yes, but not directly.

The tool that loads .Xresources, which is xrdb, invokes the C preprocessor. That's where the #include directive comes from. The C preprocessor does not provide access to environment variables. The output of the preprocessor is interpreted as a list of resources, with no further dynamic processing such as interpolation of variables.

You have two solutions: either use a different preprocessor, or define a variable when invoking xrdb and use that. Either way, you'll need to change the way xrdb is invoked — add an xrdb command to your X session startup scripts.

To use a variable with the C preprocessor, pass it on the xrdb command line:

xrdb -DEXTRA_RESOURCES_FILE="<$env_path/abc/def/Xresources>" -merge ~/.Xresources

and use that variable in your file:

#include EXTRA_RESOURCES_FILE

Note that you're limited in what you can in an include directive because the preprocessor doesn't have any string processing capability, not even concatenation. The whole file name has to be specified as a single string. Furthermore xrdb seems to silently transform " into _, but fortunately it lets <> through.

If you want more flexibility, you can use a different preprocessor. I use m4, which is quirky and not ideal, but not worse than the C preprocessor. M4 has actual string processing capabilities and can include other files. It can't access environment variables directly, however. With GNU m4, you can do it but you have to use a shell escape. If you're going to run a custom xrdb invocation, you might as well pass the environment variable at that point.

xrdb -D"env_path=$env_path" -merge ~/.Xresources

In the .Xresources file:

m4_include(env_path/abc/def/Xresources)

Note that m4 uses `…' to quote strings. To include a ` in the output, you need to temporarily change the quote character.

Alternatively, if all you need is to include one extra file, just run

xrdb -merge "$env_path/abc/def/Xresources"

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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