Docker расширение параметра cp в powershell - PullRequest
1 голос
/ 28 мая 2020

Я хотел бы запустить что-то вроде этого:

$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"

Результат:

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

Если я жестко закодирую команду docker cp, она будет работать, и если я использую следующее, это работает:

docker cp iar_build_container:C:/docker_work/IAR/Debug $docker_artifacts/Debug

Итак, у меня возникла проблема с расширением того, что было бы первым параметром, который является именем контейнера и двоеточием.

EDIT: это работает, но это кажется хакерским:

$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

Ответы [ 2 ]

2 голосов
/ 28 мая 2020

Как вы его определили, docker cp на самом деле рассматривает $cp_arguments как 1 строку, поэтому он жалуется на 2 аргумента. Посмотрите ниже

docker cp "iar_build_container:C:/docker_work/IAR/Debug $docker_artifacts/Debug"

И если вы попытаетесь запустить его в таким образом он потерпит неудачу.

Попробуйте описанный ниже подход, в котором вы не передаете "" в $cp_arguments

docker cp $cp_arguments

Вы уже определили другой способ в вопросе, который немного хакерский, но будет еще один подход.

$docker_container_name = "iar_build_container"
...
$cp_arguments_src =  $docker_container_name + ":C:/docker_work/IAR/Debug "
$cp_argument_dest =  $docker_artifacts + "/Debug"

"Copying out the build artifacts: $cp_arguments"
docker cp "$cp_arguments_src" "$cp_argument_dest"
1 голос
/ 28 мая 2020

Чтобы развернуть ответ @nishaygoyal. Запуск исполняемых файлов (например, docker) в PowerShell отличается от запуска исполняемых файлов в командной строке CMD. В PowerShell аргументы передаются как массив строк , а не как ряд строк, разделенных пробелами, как в приглашении CMD. Следовательно, передавая строку аргументов, разделенных пробелами, PowerShell интерпретирует ее как один аргумент и одну строку.

Следовательно, просто изменяя ваши аргументы в массив строк и перемещая «cp» как один из тех предметов. Все будет работать:

$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:

Как указал @Nick, мы должны использовать оператор подвыражения: $($docker_container_name) в строке, чтобы сделать правильно расширение строки, поскольку PowerShell интерпретирует $docker_container_name:C: как переменную вместо $docker_container_name. В PowerShell двоеточие указывает область действия переменной, например $global:foo. Итак, нам нужно использовать оператор подвыражения $(), чтобы правильно определить нашу переменную для расширения строки.


Почему использование Start-Process как это работает?

$cp_arguments = "cp " + $docker_container_name + ":C:/docker_work/IAR/Debug " + `
                        $docker_artifacts + "/Debug"

Start-Process -FilePath "docker" -ArgumentList "$cp_arguments" -Wait

Ну, согласно Start-Process он особенный в том, что -ArgumentList может принимать список аргументов, разделенных пробелами, и обрабатывает их в стиле подсказки CMD.

Мы также можем использовать EchoArgs , чтобы точно увидеть, что передается в качестве аргументов:

$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"

(Обратите внимание, что мы передаем 2 аргумента, cp и остальную часть строки. Vs. передача массива :

$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

В этом случае вы можете видеть, что он "правильно" разбивает аргументы

...