I would like to run something like this:
$docker_container_name = "iar_build_container"
...
$cp_arguments = $docker_container_name + ":C:/docker_work/IAR/Debug " + $docker_artifacts + "/Debug"
"Copying out the build artifacts: $cp_arguments"
docker cp "$cp_arguments"
The output of this is:
Copying out the build artifacts: iar_build_container:C:/docker_work/IAR/Debug ./docker_artifacts/Debug
"docker cp" requires exactly 2 arguments.
See 'docker cp --help'.
Usage: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
Copy files/folders between a container and the local filesystem
If I hard code the docker cp command it works, and if I use the following it works:
docker cp iar_build_container:C:/docker_work/IAR/Debug $docker_artifacts/Debug
So I am having an issue expanding what would be the first parameter that is the container name and colon.
EDIT: This works, but it feels hacky:
$cp_arguments = "cp " + $docker_container_name + ":C:/docker_work/IAR/Debug " + `
$docker_artifacts + "/Debug"
"Copying out the build artifacts: $cp_arguments"
Start-Process -FilePath "docker" -ArgumentList "$cp_arguments" -Wait
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"