'kubectl patch'适用于Linux Bash但不适用于Windows Powershell ISE

问题描述 投票:1回答:2

以下命令在Ubuntu bash上正常工作:

kubectl patch deployment wapi-backend-d1 --patch '{"spec": {"template": {"metadata": {"labels": {"date": "test"}}}}}'

相同的命令在Windows Powershell控制台(ISE)中不起作用。

错误是:

kubectl : Error from server (BadRequest): invalid character 's' looking for beginning of object key string
At line:1 char:1
+ kubectl patch deployment wapi-backend-d1 --patch '{"spec": {"template ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Error from serv...ject key string:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

powershell控制台版本是:

PS > $PSVersionTable

Name                           Value                                                                                                                                                                                                                             
----                           -----                                                                                                                                                                                                                             
PSVersion                      5.1.14409.1005                                                                                                                                                                                                                    
PSEdition                      Desktop                                                                                                                                                                                                                           
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                                                                                                                                           
BuildVersion                   10.0.14409.1005                                                                                                                                                                                                                   
CLRVersion                     4.0.30319.42000                                                                                                                                                                                                                   
WSManStackVersion              3.0                                                                                                                                                                                                                               
PSRemotingProtocolVersion      2.3                                                                                                                                                                                                                               
SerializationVersion           1.1.0.1            

我已尝试使用不同的修补值的命令,因为我看到有人写道,如果已经应用补丁可能会失败。

路径/ spec / template / metadata / labels / date确实存在于部署的yaml中,因此这也不是问题。

我认为它可能与kubectl在Powershell中使用与引号相关的工作方式有所不同,但无法找到使其工作的方法。

我试过了

kubectl patch deployment wapi-backend-d1 --patch "{\"spec\": {\"template\": {\"metadata\": {\"labels\": {\"date\": \"test123\"}}}}}"

但结果是

Error from server (NotFound): deployments.extensions "spec\\: {\\template\\: {\\metadata\\: {\\labels\\: {\\date\\: \\test123\\}}}}}" not found

Powershell上的命令应该是什么?

powershell syntax parameter-passing kubectl quoting
2个回答
2
投票

有关详细且非常有用的背景信息,请参阅answer by mklement0

在经历了很多挫折之后,我决定列出我试过的所有变种报价,并提出了一个,突然之间的工作!所以,在这里分享:

kubectl patch deployment wapi-backend-d1 --patch '{\"spec\": {\"template\": {\"metadata\": {\"labels\": {\"date\": \"test123\"}}}}}'

这是如何使用带有Powershell的kubectl补丁

另外值得注意的是:我实际上是尝试使用时间戳来修补它以触发滚动更新而不更改容器图像的标记(因此设置图像对我没有帮助)。

当您尝试将JSON放入变量然后使用变量调用kubectl补丁时,再次转义会遇到麻烦。这就是我最终得到的结果:

$patchRequest = @{
    spec = @{
        template = @{
            metadata = @{
                labels = @{
                    date = ((((Get-Date -Format o)).replace(':','-').replace('+','_')))
                }
            }
        }
    }
}
$patchJson = ((ConvertTo-Json -InputObject $patchRequest -Compress -Depth 10))
$patchJson = $patchJson.replace('"','\"')
kubectl patch deployment wapi-backend-d1 --patch $patchJson

2
投票

你在your own answer找到了正确的解决方案,但让我试着在概念上分解它:

Embedding " (double quotes) in string arguments passed to external programs:

  • (a)首先 - 合理且不可避免地 - 您需要满足PowerShell关于嵌入"字符的语法要求。在引用的字符串中。
  • (b)那么 - 这一步不应该是必要的 - 你需要\逃脱嵌入的"字符。你希望外部程序看到。 然而,只要必须保持向后兼容性,这是一个长期的,令人厌烦的错误,不太可能被修复。见this GitHub issue

Re(a),您有以下选择:

  • qazxsw poi-quoting(单引号),其中你可以使用qazxsw poi as-is: '...' "内部的所有内容都是字面意思 - 没有扩展(插值)。
  • '{ "spec": "none" }'-quoting(双引号),在其中你可以使用'...'"..."嵌入`"字符: "" - "是PowerShell的一般逃脱字符。 "{ `"spec`": `"none`" }" - `特定的逃逸(加倍) "{ ""spec"": ""none"" }"的内容受扩展(插值)的影响,这意味着你可以在这些字符串中引用变量(")或子表达式("..."),PowerShell将其替换为它们的值 - 有关PowerShell可扩展字符串的更多信息,请参阅$var

如果您将此类字符串传递给其他PowerShell命令(cmdlet,函数或脚本),则无需进一步操作;例如。:

$(1 + 2)

Re(b) - 即将这些字符串传递给外部程序 - 你还需要this answer逃脱嵌入的PS> Write-Output '3" of rain' 3" of rain 字符:

  • 将手动转义应用于上面的示例: \ " '{ \"spec\": \"none\" }'
  • 以编程方式将转义应用于预先存在的字符串: "{ \`"spec\`": \`"none\`" }"
  • 也就是说,对于外部程序最终看到字面值"{ \""spec\"": \""none\"" }",您必须从PowerShell传递字面值$str = '3" of rain'; $escapedStr = $str -replace '"', '\"'。这个3" of rain-escaping是PowerShell作为shell应该在幕后自动完成的东西,但目前没有。
  • Windows PowerShell中还有一个错误 - 自从在PowerShell Core中修复 - 错误处理了嵌入式3\" of rain字符不平衡的字符串。如果\是第一个单词的一部分: 例如,上述技术不适用于像"这样的文字值 - 相反,你必须使用以下怪物:",这在技术上是一系列独立的,不带引号的参数,这意味着(a)在单词之间有多个空格。不支持字符串(它们折叠到单个空格)和(b)PowerShell元字符(如3" of rain)必须单独进行`"3\`" of rain`"转义。 请注意,只有当& < > $ & | @ {是值中第一个单词的一部分时,并且仅当第一个单词前面没有空格时才会出现错误(尽管带有前导空格的参数很少有用);例如,`将再次起作用,因为不平衡的"不是第一个单词的一部分。

Ef。:

'3 \" of rain'
© www.soinside.com 2019 - 2024. All rights reserved.