Runtime: Environment.ExpandEnvironmentVariables on Linux has Windows behavior

Created on 6 Apr 2018  路  6Comments  路  Source: dotnet/runtime

Environment.ExpandEnvironmentVariables() on Linux expands variables in %VAR_NAME% format rather than $VAR_NAME.

SDK version: 2.1.4
OS: Ubuntu 16.04

A simple test:

Environment.ExpandEnvironmentVariables("$HOME/test");

Expected value: /home/{user}/test
Actual value: $HOME/test

However running:

Environment.ExpandEnvironmentVariables("%HOME%/test");

gives expanded result /home/{user}/test.

Design Discussion api-suggestion area-System.Runtime

Most helpful comment

Further there wouldn't be any breaking changes, since %var% and $var would work.

Except $var on Windows may start to be reinterpreted, changing output in some cases.

All 6 comments

My guess is this was done intentionally -- so existing code passing %VAR_NAME% "just works" when used on Unix. For code written for Unix, it is certainly unexpected.
The API could also respect $ - if it is worth diverging further and becoming potentially confusing.
Another option is an API
```c#
public string Environment.ExpandEnvironmentVariables(string name, EnvironmentVariablesExpandFlavor flavor = EnvironmentVariablesExpandFlavor.PlatformDefault);

[Flags]
public enum EnvironmentVariablesExpandFlavor
{
PlatformDefault = 0x1,
PercentSigns = 0x2,
DollarSigns = 0x4
}
```
with better names...

Maybe @stephentoub recalls context.

Maybe @stephentoub recalls context.

Mainly because that's how it's documented:
https://docs.microsoft.com/en-us/dotnet/api/system.environment.expandenvironmentvariables

A string containing the names of zero or more environment variables. Each environment variable is quoted with the percent sign character (%).

I could be convinced that you'd never do that on unix and this is really just surfacing a Windows-ism and so we should use $ on unix instead of %. But we'd want to understand how badly breaking that would be. I'd be worried that code has already done string.Replace('$','%') to make it work the desired way on unix, and then we'd be breaking those folks, for example.

I think we should add a new overload that supports this.

I'd be worried that code has already done string.Replace('$','%') to make it work the desired way on unix,

ps - string.Replace('$', '%') would add $ suffixes to your expanded env vars 馃槈

For cross-platform development both variants should be allowed, similar to the path-separator (\ vs. /).

_Batch_ allows the $ as valid variable name, but then it would have to be quoted by %, so %$%. This case can be handled.
In _Bash_ the % isn't allowd in variable names, so this case can be handled too.

Further there wouldn't be any breaking changes, since %var% and $var would work.

Further there wouldn't be any breaking changes, since %var% and $var would work.

Except $var on Windows may start to be reinterpreted, changing output in some cases.

It may also be worth considering expanding ~. I know that it is used by some programs in file names, so I'd suggest only expanding it if it's the first character in the given path string.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Timovzl picture Timovzl  路  3Comments

jkotas picture jkotas  路  3Comments

omajid picture omajid  路  3Comments

bencz picture bencz  路  3Comments

matty-hall picture matty-hall  路  3Comments