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

如何用Ansible将含特殊字符的命令行内容复制到文件?

解决Ansible命令行传递含特殊字符脚本的问题

问题场景

需要通过Ansible在多节点运行**动态变化且包含特殊字符(如单引号)**的脚本,使用--extra-vars传递脚本内容时,因shell的引号解析规则导致执行失败。原Playbook及执行命令如下:

原Playbook

---
- hosts: all
  become: true

  tasks:
    - name: copy extra variables to a file
      copy:
        content: |
          {{ command }}
        dest: /tmp/commands.sh
      delegate_to: localhost

    - name: copy commands.sh to nodes
      copy:
        src: /tmp/commands.sh
        dest: /tmp/
        mode: 0755

    - name: run the commands in the nodes
      shell: /bin/bash /tmp/commands.sh
      register: command_output

    - name: print output
      debug:
        msg: "{{ command_output.stdout_lines }}"

原执行命令(存在问题)

ansible-playbook -i hosts.ini store-in-file-and-run-in-nodes.yaml -e "command='
date
ps -ef | grep httpd
echo "That's all folks"
'
"

上述命令因echo "That's all folks"中的单引号导致shell解析中断,无法完整传递脚本内容。


解决方案

方案1:使用JSON格式传递--extra-vars

bash对单引号嵌套的处理非常繁琐,改用JSON格式定义变量可以绕过shell的引号解析问题,完整保留脚本内容:

多行JSON写法(推荐)

ansible-playbook -i hosts.ini store-in-file-and-run-in-nodes.yaml -e @- <<EOF
{
  "command": "date
ps -ef | grep httpd
echo \"That's all folks\""
}
EOF

通过@-读取标准输入的JSON内容,脚本中的特殊字符无需额外转义,直接原样写入即可。

单行JSON写法

ansible-playbook -i hosts.ini store-in-file-and-run-in-nodes.yaml -e '{"command": "date\nps -ef | grep httpd\necho \"That'\''s all folks\""}'

注意:单行JSON中换行需用\n表示,内部单引号需用'\''转义(适合短脚本)。


方案2:通过本地文件传递脚本内容

如果脚本内容较长或特殊字符较多,直接在命令行输入不便,可以将脚本变量定义写入本地文件,再通过--extra-vars引用:

  1. 创建script_vars.yaml文件,内容如下:
command: |
  date
  ps -ef | grep httpd
  echo "That's all folks"
  1. 执行Playbook时引用该文件:
ansible-playbook -i hosts.ini store-in-file-and-run-in-nodes.yaml -e "@script_vars.yaml"

这种方式完全避免了命令行的引号问题,脚本内容可原样保存。


方案3:简化Playbook流程(跳过本地临时文件)

原Playbook中先在localhost生成脚本再复制到节点的步骤可以简化,直接在目标节点创建脚本文件,减少中间环节:

修改后的Playbook:

---
- hosts: all
  become: true

  tasks:
    - name: Create script file on target nodes
      copy:
        content: "{{ command }}"
        dest: /tmp/commands.sh
        mode: 0755

    - name: Run the script
      shell: /bin/bash /tmp/commands.sh
      register: command_output

    - name: Print output
      debug:
        msg: "{{ command_output.stdout_lines }}"

配合方案1或方案2的变量传递方式,可高效完成脚本分发与执行。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 05:33:17