【问题标题】:Issue in ansible playbook command?ansible playbook命令中的问题?
【发布时间】:2019-11-21 03:55:53
【问题描述】:

我正在尝试在我的机器上的其他机器上的 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"

但我得到以下错误

致命:[命令任务]:失败! => {“改变”:真,“cmd”:“码头工人 exec cli -it bash -l -c echo '{\"payload\":{\"header\":{\"channel_header\":{\"channel_id\":\"gll\", \"type\":2}},\"data\":{\"config_update\":'$(cat jaguar_update.json)'}}}' | 。 > jaguar_update_in_envelope.json", “增量”:“0:00:00.110341”,“结束”:“2019-07-12 10:21:45.204049”,“味精”: "非零返回码", "rc": 4, "start": "2019-07-12 10:21:45.093708", "stderr": "cat: jaguar_update.json: 没有这样的文件或 目录\n解析错误:第 1 行第 4 列的数字文字无效", "stderr_lines": ["cat: jaguar_update.json: 没有这样的文件或目录", “解析错误:第 1 行第 4 列的数字文字无效”]、“stdout”: "", "stdout_lines": []}

工作目录中存在的所有文件“jaguar_update.json”。我已经确认了工作目录。

如果我将上面的命令放在 shell 脚本文件中,然后从 ansible 执行 shell 脚本,则上述命令有效。

【问题讨论】:

  • 你可以试试docker exec -it cli bash -l -c 交互式终端的-it 选项。试试看。
  • 它不起作用
  • 可以试试shell模块吗?
  • 此处需要 shell 而不是 command。管道和重定向不适用于command。下一个问题将是嵌套引用。
  • 这里的shell应该如何使用?

标签: shell docker ansible hyperledger-fabric


【解决方案1】:

正如大家所提到的,这确实需要您使用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

现在在 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"
      }
    }
  }
}

【讨论】:

  • 这似乎比我自己的答案更详细。赞成。
【解决方案2】:

为避免任何复杂性,请尝试as in this question 将您的命令包装在脚本中,然后调用该脚本(使用commandshell

- 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\":...

【讨论】:

  • 哈哈。这就是我现在所做的修复它。但我也在寻求 ansible 的解决方案:-)
  • @DhirajKumar 我明白了。但经过多次试验,我最终也这样做了:使用脚本。
  • 谢谢@Vonc。我想那我们只剩下 shell 脚本解决方案了
  • @DhirajKumar 我同意:让我们等待您的赏金结束,看看是否有人提供更好的解决方案。
【解决方案3】:

参考docs -

  • 命令将不会通过 shell 处理,因此 $HOME 等变量和“”、“|”、“;”等操作而“&”将不起作用。如果您需要这些功能,请使用 shell 模块。

shell 确实是向 sh 命令解析器提交了一个脚本。

另一个注意事项 - 您在 $(cat jaguar_update.json) 之前结束单引号并在之后重新启动它,但不要在其周围使用任何双引号。你的输出可能会处理这个问题,但我想提请注意以防万一。

【讨论】:

    猜你喜欢
    • 2020-03-29
    • 2020-12-04
    • 2013-12-09
    • 1970-01-01
    • 2018-02-07
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 2017-09-18
    相关资源
    最近更新 更多