You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ansible Playbook中运行含引号、括号与重定向的命令

在Ansible Playbook中正确执行修改composer.json的bash命令

我有一条可正常执行的bash命令,用于给composer.json添加PSR-4自动加载规则:

cat <<< $(jq --indent 4 '.autoload."psr-4" += { "Modules": "Modules/" }' me/composer.json) > me/composer.json

但将其放入Ansible Playbook中执行时出现多种错误,以下是尝试过程及解决方案:


尝试1:使用shell模块

Playbook代码

---

- name: modules autoload
  shell: |
    cat <<< $(jq --indent 4 '.autoload."psr-4" += { "Modules": "Modules/" }' me/composer.json) > me/composer.json

报错信息

fatal: [127.0.0.1]: FAILED! => {"changed": true, "cmd": "cat <<< $(jq --indent 4 '.autoload.\"psr-4\" += { \"Modules\\\": \"Modules/\" }' me/composer.json) > me/composer.json", "delta": "0:00:00.001537", "end": "2023-03-13 01:06:28.268890", "msg": "non-zero return code", "rc": 2, "start": "2023-03-13 01:06:28.267353", "stderr": "/bin/sh: 1: Syntax error: redirection unexpected", "stderr_lines": ["/bin/sh: 1: Syntax error: redirection unexpected"], "stdout": "", "stdout_lines": []}

错误原因

Ansible的shell模块默认使用/bin/sh执行命令,而<<<(here-string)是bash专属特性,并非所有sh兼容shell都支持,因此触发语法错误。


尝试2:使用command模块

Playbook代码

---

- name: modules autoload
  command: |
    cat <<< $(jq --indent 4 '.autoload."psr-4" += { "Modules": "Modules/" }' me/composer.json) > me/composer.json

报错信息

fatal: [127.0.0.1]: FAILED! => {"changed": true, "cmd": ["cat", "<<<", "$(jq", "--indent", "4", ".autoload.\"psr-4\" += { \"Modules\\\": \"Modules/\" }", "me/composer.json)", ">", "me/composer.json"], "delta": "0:00:00.001982", "end": "2023-03-13 01:08:33.239162", "msg": "non-zero return code", "rc": 1, "start": "2023-03-13 01:08:33.237180", "stderr": "cat: unrecognized option '--indent'\nTry 'cat --help' for more information.", "stderr_lines": ["cat: unrecognized option '--indent'", "Try 'cat --help' for more information."], "stdout": "", "stdout_lines": []}

错误原因

command模块不会通过shell解析命令,会直接把重定向符号<<<、>和命令替换$(...)全部当成cat的参数,导致命令执行逻辑完全混乱。


可行解决方案

方案1:指定shell模块使用bash

修改shell模块配置,明确指定用bash执行命令,同时调整引号包裹避免YAML解析干扰:

- name: Add Modules PSR-4 autoload to composer.json
  shell: |
    cat <<< "$(jq --indent 4 '.autoload."psr-4" += { "Modules": "Modules/" }' me/composer.json)" > me/composer.json
  executable: /bin/bash

方案2:简化命令,避免here-string

直接让jq输出到临时文件再替换原文件(不能直接覆盖原文件,否则jq会读取空文件):

- name: Add Modules PSR-4 autoload to composer.json
  shell: |
    jq --indent 4 '.autoload."psr-4" += { "Modules": "Modules/" }' me/composer.json > temp.json && mv temp.json me/composer.json

方案3:使用Ansible JSON模块(最佳实践)

推荐用Ansible内置的community.general.json模块修改JSON文件,无需依赖jq,更符合配置管理理念:

  1. 先安装依赖集合:
ansible-galaxy collection install community.general
  1. 编写Playbook:
- name: Add Modules PSR-4 autoload to composer.json
  community.general.json:
    path: me/composer.json
    pretty: true
    pretty_print_width: 4
    state: present
    key: autoload.psr-4.Modules
    value: Modules/

内容的提问来源于stack exchange,提问作者4n70wa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 00:55:13