To expand on @nishaygoyal answer. Running executables (e.g. docker) in PowerShell is different than running executables in CMD prompt. In PowerShell, arguments are passed as an array of strings, and not as a space separated series of strings like in CMD prompt. Hence by passing the space separated string of arguments, PowerShell is interpreting it as a single argument, and a single string.
Hence, by simply changing your arguments into an array of strings, and moving the "cp" as one of those items. Things will work:
$docker_container_name = "iar_build_container"
$docker_artifacts = "./docker_artifacts"
$cp_arguments = @("cp", `
"$($docker_container_name):C:/docker_work/IAR/Debug", `
"$docker_artifacts/Debug")
docker $cp_arguments
EDIT:
As @Nick pointed out, we have to use the subexpression operator: $($docker_container_name)
in the string to do proper string expansion because PowerShell will interpret $docker_container_name:C:
as a variable instead of $docker_container_name
. To PowerShell, the colon indicates the scope of the variable, e.g. $global:foo
. So we need to use the subexpression operator $()
to properly define our variable for string expansion.
Why does using Start-Process
like this work?
$cp_arguments = "cp " + $docker_container_name + ":C:/docker_work/IAR/Debug " + `
$docker_artifacts + "/Debug"
Start-Process -FilePath "docker" -ArgumentList "$cp_arguments" -Wait
Well, according to Start-Process it's special in that the -ArgumentList
can accept a space separated list of arguments, and it treats them in a CMD prompt style way.
We also can use EchoArgs to see exactly what is being passed as arguments:
$docker_container_name = "iar_build_container"
$docker_artifacts = "./docker_artifacts"
#Original:
$cp_arguments = $docker_container_name + ":C:/docker_work/IAR/Debug " + $docker_artifacts + "/Debug"
PS C:\> EchoArgs.exe docker cp "$cp_arguments"
Arg 0 is <docker>
Arg 1 is <cp>
Arg 2 is <iar_build_container:C:/docker_work/IAR/Debug ./docker_artifacts/Debug>
Command line:
"C:\ProgramData\chocolatey\lib\echoargs\tools\EchoArgs.exe" docker cp "iar_build_container:C:/docker_work/IAR/Debug ./docker_artifacts/Debug"
(Notice that we are passing 2 arguments, cp
, and the rest of the string. vs. passing an array:
$cp_arguments = @("cp", `
"$($docker_container_name):C:/docker_work/IAR/Debug", `
"$docker_artifacts/Debug")
PS C:\> EchoArgs.exe docker $cp_arguments
Arg 0 is <docker>
Arg 1 is <cp>
Arg 2 is <iar_build_container:C:/docker_work/IAR/Debug>
Arg 3 is <./docker_artifacts/Debug>
Command line:
"C:\ProgramData\chocolatey\lib\echoargs\tools\EchoArgs.exe" docker cp iar_build_container:C:/docker_work/IAR/Debug ./docker_artifacts/Debug
In this case, you can see it splits out the arguments "correctly"