Docker powershell中的cp参数扩展
Docker cp parameter expansion in powershell
我想要运行这样的东西:
$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
所以我在扩展第一个参数(即容器名称和冒号)时遇到了问题。
编辑:
这行得通,但感觉很糟糕:
$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
您定义它的方式,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"
扩展@nishaygoyal 的回答。 PowerShell 中的 运行 个可执行文件(例如 docker)不同于 CMD 提示符中的 运行 个可执行文件。在 PowerShell 中,参数作为 字符串数组 传递,而不是像在 CMD 提示符中那样作为 space 分隔的字符串系列传递。因此,通过传递 space 分隔的参数字符串,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
编辑:
正如@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
可以接受 space 分隔的参数列表,并以 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
,以及字符串的其余部分。与传递数组相比:
$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
在这种情况下,您可以看到它拆分了参数 "correctly"
我想要运行这样的东西:
$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
所以我在扩展第一个参数(即容器名称和冒号)时遇到了问题。
编辑: 这行得通,但感觉很糟糕:
$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
您定义它的方式,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"
扩展@nishaygoyal 的回答。 PowerShell 中的 运行 个可执行文件(例如 docker)不同于 CMD 提示符中的 运行 个可执行文件。在 PowerShell 中,参数作为 字符串数组 传递,而不是像在 CMD 提示符中那样作为 space 分隔的字符串系列传递。因此,通过传递 space 分隔的参数字符串,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
编辑:
正如@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
可以接受 space 分隔的参数列表,并以 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
,以及字符串的其余部分。与传递数组相比:
$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
在这种情况下,您可以看到它拆分了参数 "correctly"