我正在尝试从本机在其他计算机上的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"
通过一本有趣的剧本,出现以下错误。
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"
但是我得到以下错误
致命:[命令任务]:失败! => {“ changed”: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:没有此类文件或 目录\ nparse错误:第1行第4列的数字常量无效, “ stderr_lines”:[“ cat:jaguar_update.json:没有这样的文件或目录”, “解析错误:第1行第4列的无效数字文字”],“ stdout”: “”,“ stdout_lines”:[]}
工作目录中存在的所有文件'jaguar_update.json'。我已经确认了工作目录。
如果我将其放在Shell脚本文件中,然后从ansible执行Shell脚本,上述命令将起作用。
答案 0 :(得分:3)
正如每个人都提到的那样,这确实需要您使用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
,它需要我们将整个命令作为一个参数传递,
$ 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
现在陷入困境
- 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"
}
}
}
}
答案 1 :(得分:1)
c.f。 docs-
shell实际上是将脚本提交给sh命令解析器。
另一注-在<a href="/SM/AddSMHome/" title="Add New Student" class="rotateImage">
<img src="/icon/SM_add_student3.png" class="img- responsive img-circle img-thumbnail" style="max-width: 100px;max-height: 100px;" alt="Add New Student"></a>
之前结束单引号,然后在$(cat jaguar_update.json)
之后重新启动,但不要在其周围使用任何双引号。您的输出可能会解决该问题,但是如果有必要,我想引起注意。
答案 2 :(得分:0)
为避免任何复杂性,请尝试as in this question将命令包装在脚本中,然后调用该脚本(使用command
或shell
)
- name: Add header
raw: /path/to/script/docker-add-header.sh
在/path/to/script/docker-add-header.sh
中:
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
尝试使脚本首先单独运行(无Ansible)。
请参阅(如果它不起作用,即使在任何Ansible调用之外也是如此)以转义嵌套的双引号:
docker exec cli -it bash -l -c "echo '{\"payload\":{\"header\":...