使用ansible 2.7.5,我正在尝试创建多行布尔参数。
我首先通过以下方法验证了它可以按预期运行:
FOOD: apple
IS_FRUIT: '{% if FOOD == "carrot" %}false{% elif FOOD == "apple" or FOOD == "banana" %}true{% endif %}'
然后是任务:
- name: "FOOD is: {{ FOOD }}"
debug: msg="FOOD is {{ FOOD }} where IS_FRUIT {{ IS_FRUIT | bool }}"
打印:
ok: [localhost] => {
"msg": "FOOD is apple where IS_FRUIT [ True ]"
}
运行时如预期。
基于:
In YAML, how do I break a string over multiple lines?
然后我尝试了:
IS_FRUIT: >-
{% if FOOD == "carrot" %}false
{% elif FOOD == "apple" or FOOD == "banana" %}true
{% endif %}
但会打印:
ok: [localhost] => {
"msg": "FOOD is apple where IS_FRUIT [ False ]"
}
这是错误的。我发现这篇文章描述了类似的问题: https://github.com/ansible/ansible/issues/18142
但它并没有真正提供解决方案。关于如何在Ansible中创建多行布尔变量的任何建议?
基于以下答案,我也尝试过:
FOOD: apple
IS_FRUIT: |
{% if FOOD == "carrot" %}false
{% elif FOOD == "apple" or FOOD == "banana" %}true
{% endif %}
但是当我用上面的相同任务运行它时,我仍然得到:
ok: [localhost] => {
"msg": "FOOD is apple where IS_FRUIT False"
}
这是错误的。
答案 0 :(得分:4)
令人生厌的解释
IS_FRUIT: >-
{% if FOOD == "carrot" %}false
{% elif FOOD == "apple" or FOOD == "banana" %}true
{% endif %}
请注意,在YAML中,折叠的块标量(以>
开头)将单个换行符替换为空格(将多个换行符替换为一个换行符)。所以上面的代码等同于
IS_FRUIT: >-
{% if FOOD == "carrot" %}false {% elif FOOD == "apple" or FOOD == "banana" %}true {% endif %}
因此,在Jinja处理之后,您将得到false
或true
带有尾随空格。由于存在尾随空格,YAML不会将这些标量映射为布尔值。
现在,我猜,Ansible看到它获得了一个非布尔值,并且以某种方式将该非布尔值映射为一个布尔值。因此,即使标量为False
且尾随空格,标量的计算结果也仍然为true
(markdown不能让我正确地呈现它)。
有关如何修复的重要部分
您可以改用文字块标量(根据 clockworknet 的建议):
IS_FRUIT: |-
{% if FOOD == "carrot" %}false
{% elif FOOD == "apple" or FOOD == "banana" %}true
{% endif %}
之所以起作用,是因为现在换行符不会转换为空格,而是保留换行符。在Jinja处理之后,仅剩下一行,并且最后的换行符将被-
中的|-
剥离。
但是,如果您有更复杂的表达式要在其中将内容实际拆分为多行,这将无济于事。有一个更好的解决方案是Jinja whitespace control:
IS_FRUIT: >-
{% if FOOD == "carrot" %}false
{%- elif FOOD == "apple" or FOOD == "banana" %}true
{%- endif %}
Jinja标签上的-
告诉Jinja在此标签之前删除 all 所有空格,因此,这基本上等同于
IS_FRUIT: >-
{% if FOOD == "carrot" %}false{% elif FOOD == "apple" or FOOD == "banana" %}true{% endif %}
您也可以像这样-%}
一样使用它来删除标签 之后的所有空格。但是,请注意:Jinja处理发生在YAML处理之前,因此它可能会破坏您精心编写的YAML缩进!例如,不要在块标量中的第一个Jinja标签上使用{%-
,因为Jinja会将文本与|-
放在同一行,这是无效的YAML!最后一个标签和-%}
也是如此。
答案 1 :(得分:1)
尼斯解释发生了什么由@flyx回事。
我建议避免使用金贾的语句的,从而有利于神社你的剧本的表达式的。
在文件模板中还可以执行静态语句。
您可以如下编写vars定义:
IS_FRUIT: >-
{{ false if FOOD == 'carrot'
else
(
true if FOOD in ['apple', 'banana']
else 'unknown'
)
}}
在此情况下,我们只关心被剥去与最后换行符>-
。
答案 2 :(得分:-1)
这对我有用:
IS_FRUIT: |
{% if FOOD == "carrot" %}false
{% elif FOOD == "apple" or FOOD == "banana" %}true
{% endif %}
(更改为|
符号以使用文字多行行为)