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

Ansible循环中json_query结果追加闭合方括号致scp失败

Ansible中json_query返回列表引发scp执行失败的解决办法

问题现象

循环迭代时,json_query提取的路径列表被直接插入scp命令,导致命令中出现方括号[],拼接路径后变成['/path/to/dir1']/data,最终scp因找不到路径/path/to/dir1]/data执行失败。

错误输出

failed: [node1] (item={'source_path': ['/path/to/dir1/data/snapshot.20230414003127854', '/path/to/dir2/data/snapshot.20230414003128467', '/path/to/dir3/data/snapshot.20230414003129100', '/path/to/dir4/data/snapshot.20230414003129744'], 'target_path': ['/path/to/dir1', '/path/to/dir2', '/path/to/dir3', '/path/to/dir4']}) => {
    "ansible_loop_var": "item",
    "changed": true,
    "cmd": "scp -r -o StrictHostKeyChecking=no ['/path/to/dir1/data/snapshot.20230414003127854', '/path/to/dir2/data/snapshot.20230414003128467', '/path/to/dir3/data/snapshot.20230414003129100', '/path/to/dir4/data/snapshot.20230414003129744'] user@target_node:['/path/to/dir1', '/path/to/dir2', '/path/to/dir3', '/path/to/dir4']/data",
    "delta": "0:00:00.011310",
    "end": "2023-04-13 19:31:43.326500",
    "invocation": {
        "module_args": {
            "_raw_params": "scp -r -o StrictHostKeyChecking=no ['/path/to/dir1/data/snapshot.20230414003127854', '/path/to/dir2/data/snapshot.20230414003128467', '/path/to/dir3/data/snapshot.20230414003129100', '/path/to/dir4/data/snapshot.20230414003129744'] user@target_node:['/path/to/dir1', '/path/to/dir2', '/path/to/dir3', '/path/to/dir4']/data",
            "_uses_shell": true,
            "argv": null,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "stdin_add_newline": true,
            "strip_empty_ends": true,
            "warn": true
        }
    },
    "item": {
        "source_path": [
            "/path/to/dir1/data/snapshot.20230414003127854",
            "/path/to/dir2//data/snapshot.20230414003128467",
            "/path/to/dir3/data/snapshot.20230414003129100",
            "/path/to/dir4/data/snapshot.20230414003129744"
        ],
        "target_path": [
            "/path/to/dir1",
            "/path/to/dir2",
            "/path/to/dir3",
            "/path/to/dir4"
        ]
    },
    "msg": "non-zero return code",
    "rc": 1,
    "start": "2023-04-13 19:31:43.315190",
    "stderr": "/path/to/dir1]/data: No such file or directory",
    "stderr_lines": [
        "/path/to/dir1]/data: No such file or directory"
    ],
    "stdout": "",
    "stdout_lines": []
}

原执行代码

- name: copy files
  shell: "scp -r -o StrictHostKeyChecking=no {{ item.source_path }} user@{{ target_primary_node }}:{{ item.target_path }}/data"
  with_items:
    - { source_path: "{{ source_path.results|json_query('[].files[].path') }}", target_path: "{{ dest_path.results|json_query('[].files[].path') }}" }

问题原因

  1. json_query('[].files[].path')返回列表类型,直接在模板中引用时,Ansible会将列表渲染为带方括号和引号的字符串,导致scp把方括号当成路径的一部分。
  2. 当前with_items仅定义一个包含两个列表的元素,循环仅执行一次,尝试一次性传递所有路径给scp,不符合scp多源多目标一一对应的参数格式要求。

解决方案

方法1:用zip过滤器配对路径后循环

实现源路径与目标路径一一对应传输:

- name: copy files
  shell: "scp -r -o StrictHostKeyChecking=no {{ item.0 }} user@{{ target_primary_node }}:{{ item.1 }}/data"
  loop: "{{ source_path.results|json_query('[].files[].path') | zip(dest_path.results|json_query('[].files[].path')) | list }}"

方法2:先注册配对变量再循环

若需要更清晰的结构,可先将配对结果注册为变量:

- name: prepare path pairs
  set_fact:
    path_pairs: "{{ source_path.results|json_query('[].files[].path') | zip(dest_path.results|json_query('[].files[].path')) | list }}"

- name: copy files
  shell: "scp -r -o StrictHostKeyChecking=no {{ item.0 }} user@{{ target_primary_node }}:{{ item.1 }}/data"
  loop: "{{ path_pairs }}"

特殊场景:一次性传输所有文件到单目标

若只需将所有源文件传到同一个目标目录,可用join(' ')把列表转为空格分隔的字符串:

- name: copy all files to single target
  shell: "scp -r -o StrictHostKeyChecking=no {{ source_paths | join(' ') }} user@{{ target_primary_node }}:/path/to/target_dir/data"
  vars:
    source_paths: "{{ source_path.results|json_query('[].files[].path') }}"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:34:57