I know that you can pass environment variables to docker-compose.
docker-compose.yml
. . .
mysql:
image: mariadb:10.2
ports:
- "${DB_PORT}:3306"
. . .
$ DB_PORT=3396 docker-compose up
However this only works using bash. I am using PowerShell and am trying to find an equivalent that is only a one line command.
PS> $env:DB_PORT:3306 docker-compose up
does not work. Neither does
multiline
$env:DB_PORT=3396 `
>> docker-compose -up
The error I get is
Unexpected token 'docker-compose' in expression or statement.
If I do it one at a time it does work...
PS> $env:DB_PORT=3396
PS> docker-compose -up
Is there not way to do this in PowerShell when the equivalent in bash is ridiculously simple?
POSIX-like shells such as bash
offer a way to set environment variables in a command-scoped way, simply by prepending <varName>=<value>
pairs directly to a command, as the following example demonstrates:
$ foo=bar bash -c 'echo "[$foo]"'; echo "[$foo]"
[bar]
[]
foo=bar
defines environment variable foo
for the bash -c '...'
child process only; the next command - echo ...
- does not see this variable.
PowerShell has NO equivalent construct as of v7.4.
To add support in the future with at least similar syntax is the subject of a long-standing feature request, GitHub issue #3316.
For now, the best you can do is to define the environment variable of interest first, in a separate statement, using ;
, PowerShell's statement separator. Any external utility you invoke thereafter - which invariably runs in a child process - will see it, but note that the environment variable will remain in effect in the current PowerShell session, unless you manually remove it:
# Set the env. variable, call the command that should see it,
# remove it afterwards.
PS> $env:foo = 'bar'; bash -c 'echo "[$foo]"'; $env:foo = $null
[bar]
Note how $env:foo = $null
i.e., setting the environment variable to $null
is the same as removing it; alternatively, you could all Remove-Item env:foo
If you also want to restore a pre-existing value afterwards:
$env:foo = 'original'
# Temporarily change $env:foo to a different value, invoke the
# program that should see it, then restore the previous value.
& { $org, $env:foo = $env:foo, 'bar'; bash -c 'echo "[$foo]"'; $env:foo = $org }
$env:foo
The above yields:
[bar]
original
showing that while the bash
process saw the temporary value, bar
, the original value of $env:foo
was restored afterwards.
Also note another important difference:
In POSIX-like shells, environment variables are implicitly surfaced as shell variables - they share the one and only namespace the shell has for variables.
By contrast, PowerShell surfaces environment variables only via the $env:<varName>
namespace (e.g., $env:foo
), which is distinct from the (prefix-less) namespace for PowerShell's own variables (e.g., $foo
).