Следующая команда отлично работает в 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?
Подробную и очень полезную информацию см. в статье ответ от mklement0.
После долгих разочарований я решил перечислить все варианты экранирования кавычек, которые я пробовал, и придумал еще один, который неожиданно сработал! Итак, делимся здесь:
kubectl patch deployment wapi-backend-d1 --patch '{\"spec\": {\"template\": {\"metadata\": {\"labels\": {\"date\": \"test123\"}}}}}'
Вот как использовать патч kubectl с Powershell
Кроме того, обратите внимание: на самом деле я пытался исправить его с отметкой времени, чтобы вызвать непрерывное обновление без изменения тегов образов контейнеров (поэтому установленное изображение мне не помогло).
Когда вы пытаетесь поместить свой JSON в переменную, а затем вызываете kubectl patch с переменной, у вас снова возникают проблемы с экранированием. Вот что у меня получилось:
$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
Вы нашли правильное решение в твой собственный ответ, но позвольте мне попытаться концептуально разбить его:
"
(двойные кавычки) в строковые аргументы, передаваемые внешним программам:(a) Во-первых — разумно и неизбежно — вам нужно удовлетворить синтаксические требования PowerShell в отношении встраивания "
символов. в кавычках.
(б) Затем — и в этом шаге нет необходимости — вам нужно \
-экранировать встроенные "
символы. который вы хотите, чтобы внешние программы увидел.
Ре (а), у вас есть следующие варианты:
'...'
-кавычки (одинарные кавычки), внутри которых можно использовать "
как есть:
'{ "spec": "none" }'
'...'
берется буквально — расширения (интерполяции) не происходит."..."
-кавычки (двойные кавычки), внутри которых можно использовать `"
или ""
для встраивания "
символов:
"{ `"spec`": `"none`" }"
— `
— это общий escape-символ PowerShell."{ ""spec"": ""none"" }"
- "
-специфическое экранирование (удвоение)"..."
подлежит расширение (интерполяции), что означает, что вы можете ссылаться на переменные ($var
) или подвыражения ($(1 + 2)
) внутри таких строк, которые PowerShell заменяет их значениями — см. этот ответ для получения дополнительной информации о расширяемые строки PowerShell.Если вы передача такой строки другим командам PowerShell (командлеты, функции или скрипты), никаких дальнейших действий не требуется; например.:
PS> Write-Output '3" of rain'
3" of rain
Ре (б) - т.е. к передавать такие строки в внешние программы - вам Кроме того нужно \
-экранировать встроенные "
символы.:
Применение экранирования руководство к приведенным выше примерам:
'{ \"spec\": \"none\" }'
"{ \`"spec\`": \`"none\`" }"
"{ \""spec\"": \""none\"" }"
Применение экранирование программно к уже существующей строке:
Замените дословно "
на дословно \"
, а также любые ранее существовавшие непосредственно предшествующий\
на \\
:
$str = '3" of rain'; $escapedStr = $str -replace '([\\]*)"', '$1$1\"'
То есть, чтобы внешняя программа в конечном итоге увидела значение 3" of rain
дословно, вы должны передать буквальное значение 3\" of rain
из PowerShell. Это \
-экранирование — это то, что PowerShell, как оболочка, должен делать автоматически за кулисами, но в настоящее время этого не делает.
Есть дополнительная ошибка в Windows PowerShell — с момента исправления в PowerShell Основной — этот неправильно обрабатывает строки со встроенными "
символами неуравновешенный. если "
это часть первого слова:
3" of rain
; то есть экранирование этого как '3\" of rain'
нет работает должным образом - вместо этого вы должны использовать следующее чудовище: `"3\`" of rain`"
, которое технически представляет собой серию отдельных аргументов без кавычек, что означает, что (а) несколько пробелов между словами строк не не поддерживаются (они свернуты в один пробел) и (b) метасимволы PowerShell, такие как & < > $ & | @ {
, должны быть индивидуально экранированы `
."
является частью первого слова в значении, и только если этому первому слову не предшествует пробел (хотя аргументы с ведущими пробелами редко бывают полезны); например, '3 \" of rain'
снова будет работать, потому что несбалансированный "
не является частью первого слова.Пример:
В следующем примере choice.exe
используется в качестве примера внешней программы, потому что ее можно переназначить (с помощью параметров /d Y /t 0
) просто на эхо предоставленную ей строку приглашения, которая показывает, как она получила строку, переданную из PowerShell:
& {
# Note: For preview versions of v7.2, deactivate the experimental
# feature that fixes the problem, so as to show the original problem.
$PSNativeCommandArgumentPassing = 'Legacy'
# Use manual \-escaping to pass what should be received as
# verbatim { "spec": "none" } to an external program.
choice /m '{ \"spec\": \"none\" }' /d Y /t 0
}
Приведенные выше результаты выводят { "spec": "none" } [Y,N]?Y
, показывая, что символы "
экранированы вручную. были получены как дословные "
символы. по внешней программе.
Можно ли получить json из файла?