Match/Include by environment variable unexpected behavior

openssh at tr.id.au openssh at tr.id.au
Mon Jan 20 11:00:35 AEDT 2025


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



More information about the openssh-unix-dev mailing list