【问题标题】:How to escape backslash and double quote in Ansible (script module)如何在 Ansible(脚本模块)中转义反斜杠和双引号
【发布时间】:2016-09-19 19:37:18
【问题描述】:

我是 Ansible (2.x) 的新手,在使用脚本模块和使用双引号和反斜杠传递参数时遇到问题。

假设我们有一个包含字符串“foo”的集合变量{{foo}},我有一个这样的任务:

set_fact:
   arg: \(-name "{{foo}}" \)
name: call shell module
script: path/somescript.sh "{{arg}}"

我的脚本需要以下参数结构才能工作:

\(-name "foo" \)

我尝试了几件事,例如:

arg: \(-name \""{{foo}}"\" \)           result: \\(-name \"foo\" \\)

arg: '\(-name \""{{foo}}"\" \)'         result: \\(-name \"foo\" \\)

arg: \\(-name \""{{foo}}"\" \\)           result: \\(-name \"foo\" \\)

是否可以在 Ansible 中转义反斜杠和双引号?

【问题讨论】:

    标签: ansible


    【解决方案1】:

    不要对 ansible-playbook 以 JSON 编码形式打印调试消息这一事实感到困惑,因此某些字符会被转义。

    set_fact:
      arg: \(-name "{{foo}}" \)
    

    你有正确的语法。如果foo 的值为bar,这会将arg 设置为\(-name "bar" \)
    但是这种情况下的调试消息将如下所示:

    ok: [localhost] => {
        "arg": "\\(-name \"bar\" \\)"
    }
    

    请注意,JSON 的特殊字符("\)会被转义。

    但是将其作为参数传递可能会出现一些问题。
    如果你这样调用你的脚本

    script: path/somescript.sh "{{arg}}"
    

    参数字符串看起来像这样"\(-name "bar" \)",它实际上是 bash 中的 3 个连接字符串:\(-name +bar+ \),因此您将丢失 bar 周围的双引号。

    如果要保留这些双引号,请使用:

    script: path/somescript.sh '{{arg}}'
    

    【讨论】:

    • 单引号是解决问题的关键。你是对的,当传递给脚本时,这些字符最终会被转义。我无法投票,因为我的声誉太低了,但我要感谢你 :-)
    • 单引号完成了这项工作。感谢您的回答。
    • 我也面临同样的问题。我正在传递带有 with_items 的路径列表。当我使用 win_shell 和“{{item}}”时,反斜杠没有正确添加。我们如何在 win_shell 中使用循环变量?
    【解决方案2】:

    你很亲密。我认为您想设置一个变量,而不是事实,我建议您使用shell 模块而不是script 模块。 shell 在转义和引用复杂的 shell 命令时更加宽容。

    ---
    - hosts: localhost
      vars:
        foo: test.yml
        arg: \( -name "{{ foo }}" \)
      tasks:
        - debug: var=arg
        - shell: find . {{ arg }}
          register: find
        - debug: var=find.stdout_lines
    

    还有输出:

    $ ansible-playbook test.yml 
    
    PLAY [localhost] ***************************************************************
    
    TASK [debug] *******************************************************************
    ok: [localhost] => {
        "arg": "\\( -name \"test.yml\" \\)"
    }
    
    TASK [command] *****************************************************************
    changed: [localhost]
    
    TASK [debug] *******************************************************************
    ok: [localhost] => {
        "find.stdout_lines": [
            "./test.yml"
        ]
    }
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=3    changed=1    unreachable=0    failed=0   
    

    【讨论】:

    • 我现在正在使用 shell 脚本。结合 Konstatin Suvorov 的回答(作为 arg 传递给脚本时的单引号),这帮助了我。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-22
    相关资源
    最近更新 更多