shell - ansible playbook命令中的问题?
问题描述
我正在尝试从我的机器上在其他机器上的 docker 上执行命令。当我执行这个命令时:
- name: Add header
command: docker exec cli bash -l -c "echo '{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":'$(cat jaguar_update.json)'}}}' | jq . > jaguar_update_in_envelope.json"
通过ansible playbook,我收到如下所示的错误。
fatal:[
command-task
]:FAILED! =>{
"changed":true,
"cmd":[ ],
"delta":"0:00:00.131115",
"end":"2019-07-11 17:32:44.651504",
"msg":"non-zero return code",
"rc":4,
"start":"2019-07-11 17:32:44.520389",
"stderr":"mesg: ttyname
failed: Inappropriate ioctl for device\nparse error: Invalid numeric
literal at line 1, column 9",
"stderr_lines":[
"mesg: ttyname failed:
Inappropriate ioctl for device",
"parse error: Invalid numeric literal
at line 1, column 9"
],
"stdout":"",
"stdout_lines":[
]
}
但是,如果我在 docker 容器中手动执行命令,它可以正常工作并且我没有遇到任何问题。
编辑:正如我所建议的那样,我尝试使用shell
模块
shell: docker exec cli -it bash -l -c "echo '{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":'$(cat jaguar_update.json)'}}}' | jq . > jaguar_update_in_envelope.json"
但我得到以下错误
致命:[命令任务]:失败!=> {“更改”:true,“cmd”:“docker exec cli -it bash -l -c echo '{\“payload\”:{\“header\”:{\“channel_header\”:{\” channel_id\":\"gll\", \"type\":2}},\"data\":{\"config_update\":'$(cat jaguar_update.json)'}}}' | jq . > jaguar_update_in_envelope.json”、“delta”:“0:00:00.110341”、“end”:“2019-07-12 10:21:45.204049”、“msg”:“非零返回码”、“rc”: 4,“开始”:“2019-07-12 10:21:45.093708”,“stderr”:“cat:jaguar_update.json:没有这样的文件或目录\n解析错误:第1行第4列的数字文字无效”, “stderr_lines”:[“猫:jaguar_update.
工作目录中存在的所有文件“jaguar_update.json”。我已经确认了工作目录。
如果我把它放在一个 shell 脚本文件中,然后从 ansible 执行 shell 脚本,上面的命令就可以工作。
解决方案
正如每个人都提到的那样,这确实需要您使用shell
而不是command
. 现在您想简化此命令,以便它可以首先在 bash 中运行。这可以很容易地使用printf
$ printf "%s%s%s" '{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":' $(<jaguar_update.json'}}}' | jq . > jaguar_update_in_envelope.json
$ cat jaguar_update_in_envelope.json
{
"payload": {
"header": {
"channel_header": {
"channel_id": "gll",
"type": 2
}
},
"data": {
"config_update": {
"name": "tarun"
}
}
}
}
所以现在我们的命令运行没有问题。接下来是使用bash -l -c
格式移动它。因此,使用-c
which 需要我们将整个命令作为一个参数传递,我们使用多行命令
$ bash -l <<EOF
printf "%s%s%s" '{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":' $(<jaguar_update.json) '}}}' | jq . > jaguar_update_in_envelope.json
EOF
但这失败并出现错误
{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":{bash: line 2: name:: command not found
bash: line 3: syntax error near unexpected token `}'
bash: line 3: `} '}}}' | jq . > jaguar_update_in_envelope.json'
这是因为EOF
格式会将每个新行视为不同的命令。所以我们需要替换所有的换行符
bash -l <<EOF
printf "%s%s%s" '{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":' $(sed -E 's|"|\\"|g' jaguar_update.json | tr -d '\n') '}}}' | jq . > jaguar_update_in_envelope.json
EOF
现在在 ansible
- name: a play that runs entirely on the ansible host
hosts: 127.0.0.1
connection: local
tasks:
- name: Solve the problem
shell: |
bash -l <<EOF
printf "%s%s%s" '{"payload":{"header":{"channel_header":{"channel_id":"gll", "type":2}},"data":{"config_update":' $(sed -E 's|"|\\"|g' jaguar_update.json | tr -d '\n') '}}}' | jq . > jaguar_update_in_envelope.json
EOF
结果
$ ansible-playbook test.yml
PLAY [a play that runs entirely on the ansible host] *********************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************************************************************
ok: [127.0.0.1]
TASK [Solve the problem] *************************************************************************************************************************************************************
changed: [127.0.0.1]
PLAY RECAP ***************************************************************************************************************************************************************************
127.0.0.1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ cat jaguar_update_in_envelope.json
{
"payload": {
"header": {
"channel_header": {
"channel_id": "gll",
"type": 2
}
},
"data": {
"config_update": {
"name": "tarun"
}
}
}
}
推荐阅读
- opc-ua - 在 WINDEV 上使用 OPC UA 将一个数组(实数)写入 Siemens 1500
- eclipse - 使用 eclipse 将自动化测试与 azure devops 中的测试用例相关联
- elasticsearch - Elasticsearch 术语聚合不返回存储桶
- random-forest - 在分位数随机森林回归模型中检查树木
- csv - CSV - 如何在一个单元格中表示多个值
- amazon-web-services - 更新 EBS 卷的大小而不替换旧卷并重启 EC2 实例
- python - 如何使用 for 循环在 Python 中绘制子图
- java - 不能跑扑医生--执照
- regex - 用于在 Google Data Studio 中提取年份或月份的 REGEXP_EXTRACT 特定字符串
- ios - 无效的 UINavigationController 颜色 iPhone UISplitViewController