In my dockerfile I have the line
RUN [Environment]::SetEnvironmentVariable("Path", $env:Path ";C:\oracle\instantclient_19_10", "Machine")
I get this returned, even though when I run the above command in PowerShell everything "just works"
At line:1 char:114
... = 'SilentlyContinue'; [Environment]::SetEnvironmentVariable(Path, $e ...
~
Missing ')' in method call.
At line:1 char:114
... SilentlyContinue'; [Environment]::SetEnvironmentVariable(Path, $env:P ...
~~~~
Unexpected token 'Path' in expression or statement.
At line:1 char:118
... ilentlyContinue'; [Environment]::SetEnvironmentVariable(Path, $env:Pa ...
~
Missing argument in parameter list.
At line:1 char:162
... entVariable(Path, $env:Path ;C:\oracle\instantclient_19_10, Machine ...
~
Missing argument in parameter list.
At line:1 char:171
... ntVariable(Path, $env:Path ;C:\oracle\instantclient_19_10, Machine)
~
Unexpected token ')' in expression or statement.
CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordEx
ception
FullyQualifiedErrorId : MissingEndParenthesisInMethodCall
CodePudding user response:
The error message implies two things:
PowerShell is configured as your default shell in your dockerfile (by default it is
cmd.exe
)However, the
"
characters were stripped from your PowerShell command, which broke it.
Therefore, escape the "
character as \"
:
RUN [Environment]::SetEnvironmentVariable(\"Path\", $env:Path \";C:\oracle\instantclient_19_10\", \"Machine"\)
Alternatively, you can simply use '
-quoting in this case:
RUN [Environment]::SetEnvironmentVariable('Path', $env:Path ';C:\oracle\instantclient_19_10', 'Machine')
As for why escaping "
as \"
is needed:
Presumably, what follows
RUN
is copied as-is to thepowershell.exe -Command
command line that is used behind the scenes.During PowerShell's command-line parsing, unescaped
"
characters are removed before the resulting code is interpreted as PowerShell code. Thus,"
characters that must be retained as part of the PowerShell code must be\"
-escaped.- See this answer for a detailed explanation.
CodePudding user response:
Note: This answer isn't quite correct, check out the accepted answer https://stackoverflow.com/a/74142485/3684640 for the correct reason for why this is happening
This is an unfortunate clash with Docker's two forms of run commands referenced here https://docs.docker.com/engine/reference/builder/#run.
There's shell form:
RUN (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
And there's exec form
RUN ["executable", "param1", "param2"] (exec form)
In Powershell with the command you're trying to use "[Environment]" is at the beginning which makes Docker think we are in exec form.
A potential fix that works is
RUN ["powershell.exe", "[Environment]::SetEnvironmentVariable(\"Path\", $env:Path \";C:\\oracle\\instantclient_19_10\", \"Machine\")"]
Which works by using exec form instead of shell form, since this is in json syntax we have to escape all the necessary characters as well.