openssh at tr.id.au
2025-Jan-20 00:00 UTC
Match/Include by environment variable unexpected behavior
Hey there, I hope you had a good weekend.
I'm setting up conditional inclusion with environment variables. I thought
to use a Match block to skip inclusion when the variable is undefined. However,
it seems like when ssh client parses the config, it tries to evaluate the
variable despite Match failure.
I can give a minimal example. Let's use two ssh config files in the present
working directory:
```
$ cat testing.sshconfig
Match exec '[[ -v EXAMPLE_VARIABLE ]]'
Include ${PWD}/${EXAMPLE_VARIABLE}.sshconfig
$ cat example.sshconfig
Host foo.example.com
ProxyJump bar.example.com
```
(In case you don't have the `-v` test in your shell, I also checked with `[[
-n "$EXAMPLE_VARIABLE" ]]`.)
When the environment variable is set, it works as expected:
```
$ EXAMPLE_VARIABLE=example ssh -F ./testing.sshconfig -G foo.example.com | grep
-i proxyjump
proxyjump bar.example.com
```
When the environment variable is not set, there is an error from still trying to
expand the Include path:
```
$ ssh -F ./testing.sshconfig -G foo.example.com | grep -i proxyjump
vdollar_percent_expand: env var ${EXAMPLE_VARIABLE} has no value
./testing.sshconfig line 2: Unable to expand user config file
'${PWD}/${EXAMPLE_VARIABLE}.sshconfig'
```
I don't see this behavior called out in the manpage; in fact, the manual
seems to imply that Match failure should skip inclusions:
> Include directive may appear inside a Match or Host block to perform
conditional inclusion.
Have I overlooked something, or is there scope to delay resolution of
environment variables under a Match until after the Match is checked?
(Tested with OpenSSH_9.9p1 on Gentoo.)
Cheers,
Tim