json - 带有 JSON 到 powershell 的 Ansible win_shell,其他方式也可以正常工作
问题描述
我不知道如何让 win_shell 将 JSON 发送到 Windows 服务器上的 powershell 脚本。如果我运行这个:
vm:
annotation: This is a VM
cdrom:
type: client
iso_path: ''
controller_type: ''
state: ''
cluster: ''
- name: "Run script '.ps1'"
win_shell: D:\scripts\outputValues.ps1 -vm "{{vm}}"
register: result
- name: Process win_shell output
set_fact:
fullResult: "{{ result.stdout | from_json }}"
我把这个字符串变成了我什至无法转换为 JSON 的 powershell:
{u'cdrom': {u'controller_type': u'', u'state': u'', u'type': u'client', u'iso_path': u''}, u'cluster': u'', u'annotation': u'This is a VM'}
如果我用这个运行脚本:
win_shell: D:\scripts\outputValues.ps1 -vm "{{vm | to_json}}"
我得到的只是一个打开的大括号'{'进入powershell。
它确实以另一种方式工作。作为测试,如果我从 win_shell 调用相同的 powershell 脚本并忽略 powershell 中的输入并简单地创建一个这样的对象并将其发送回 ansible,它工作正常。为什么我可以以一种方式发送 JSON 而不能以另一种方式发送?我试过 vm|to_json 等。
#Powershell
$vmAttribs = @{"type" = "client"; "iso_path" = ""; "controller_type" =""; "state" =""}
$vmObject = New-Object psobject -Property @{
annotation = 'This is a VM'
cdrom = $vmAttribs
cluster = ""
}
$result = $vmObject | ConvertTo-Json -Depth 8
Write-Output $result
ansible 得到:
{
"msg": {
"cdrom": {
"controller_type": "",
"state": "",
"type": "client",
"iso_path": ""
},
"cluster": "",
"annotation": "This is a VM"
},
"changed": false,
"_ansible_verbose_always": true,
"_ansible_no_log": false
}
解决方案
您所看到的是一个 Python 结构,它使用 Unicode 字符串(例如u'my string value'
)表示 JSON 符号。显然,这并不能完全移植到Powershell等其他运行时,并且会导致字符串无效。
阅读Ansible 过滤器,您将希望使用它{{ vm | to_json }}
来确保将数据结构正确地字符串化为 JSON。
解决方法
我想强调的是,这不是从 Ansible 中获取 JSON 对象的理想方式,并且不涉及从 JSON 字符串中删除 Unicode 标识符的适当解决方案对此是可取的。
我对 Ansible 知之甚少,不知道为什么{
在管道vm
到时字符串会变成这样to_json
,但这里有一个解决方法可以让你继续前进,直到其他人可以在此处插入 Ansible 的过滤所发生的事情。
在您的.ps1
脚本中,您可以使用以下内容在字符串之前-replace
删除这些u
字符:
$vm = $vm -replace "u(?=([`"']).*\1)"
您可以通过在交互式终端中运行以下命令来测试:
"{u'cdrom': {u'controller_type': u'', u'state': u'', u'type': u'client', u'iso_path': u''}, u'cluster': u'', u'annotation': u'This is a VM'}" -replace "u(?=([`"']).*\1)"
该模式匹配u
紧接在单引号或双引号之前的字符,后跟任意数量的字符(包括无字符),后跟另一个单引号或双引号,以第一次匹配的为准。-replace
如果您用空字符串替换模式,则不需要第二个参数。
推荐阅读
- python-asyncio - 设置无限会话超时但限制每个请求超时
- powershell - 使用 New-Variable 函数创建变量时如何显式声明变量的类型?
- ios - 管理自动更新应用内购买和消耗性应用内购买
- algorithm - 为什么 MQTT 对剩余长度使用这种奇怪的编码方案?
- python - 在 Python 中使用多个参数映射,包括一个具有默认值的参数
- javascript - 等待“结束”的视频事件侦听器未触发
- python - 从 python 调用时,某些 powershell 命令不会运行
- ubuntu - 我可以为 Jenkins 配置文件恢复 config.xml 吗?(/var/lib/jenkins/config.xml)
- ruby-on-rails - before_action 中的 render/head 不会停止执行其余的操作
- laravel - laravel 本地化