英文:
Ansible automatically flips variable
问题
我最近遇到了Ansible的一个非常奇怪的行为,想知道为什么会发生这种情况。
我使用的是Ansible 2.7.7和Python 3.5.3。
具体来说,我有两个变量:
GLOBAL_HIGHEST_PARAM: "{5,0}"
LOCAL_HIGHEST_PARAM: "{5,0}"
并且在使用LOCAL_HIGHEST_PARAM
时,例如像这样:
- name: 设置最高分参数 {{ LOCAL_HIGHEST_PARAM }}
# ...
在运行时给我正确的输出:设置最高分参数 {5,0}
但是当我定义变量如下:
GLOBAL_HIGHEST_PARAM: "{5,0}"
LOCAL_HIGHEST_PARAM: "{{ GLOBAL_HIGHEST_PARAM }}"
我得到了不正确的输出:设置最高分参数 {0,5}
为什么会发生这种情况?
英文:
I recently came across a very strange behavior of Ansible and would like to know why this is happening.
I'm using Ansible 2.7.7 with python 3.5.3.
So to the point.
I have two variables:
GLOBAL_HIGHEST_PARAM: "{5,0}"
LOCAL_HIGHEST_PARAM: "{5,0}"
And using LOCAL_HIGHEST_PARAM
for example like this:
- name: Setting up highest score param {{ LOCAL_HIGHEST_PARAM }}
# ...
Which gives me the correct output during run: Setting up highest score param {5,0}
But when I define variables such as:
GLOBAL_HIGHEST_PARAM: "{5,0}"
LOCAL_HIGHEST_PARAM: "{{ GLOBAL_HIGHEST_PARAM }}"
I get the incorrect output: Setting up highest score param {0,5}
Why is this happening?
答案1
得分: 2
这是因为`{5,0}`实际上是一个[Python集合](https://docs.python.org/3.11/library/stdtypes.html#set-types-set-frozenset),你可以在调试变量时看到:
```yaml
- debug:
msg: "{{ GLOBAL_HIGHEST_PARAM }}"
vars:
GLOBAL_HIGHEST_PARAM: "{5,0}"
会产生:
ok: [localhost] =>
msg: !!set
0: null
5: null
由于5
和0
是集合的键,所以集合会按键排序。
你可以使用Jinja的string
过滤器强制将其表示为字符串。
任务:
- debug:
msg: "{{ LOCAL_HIGHEST_PARAM }}"
vars:
GLOBAL_HIGHEST_PARAM: "{5,0}"
LOCAL_HIGHEST_PARAM: "{{ GLOBAL_HIGHEST_PARAM | string }}"
会得到你期望的结果:
ok: [localhost] =>
msg: '{5,0}'
请注意,在任务名称中可以正常工作,因为任务名称只能是字符串,所以它会隐式转换为字符串,在其他情况下可能不会,除非使用显式的string
过滤器。
<details>
<summary>英文:</summary>
This happens because `{5,0}` is actually a [Python set](https://docs.python.org/3.11/library/stdtypes.html#set-types-set-frozenset), which you can actually see debugging the variable:
```yaml
- debug:
msg: "{{ GLOBAL_HIGHEST_PARAM }}"
vars:
GLOBAL_HIGHEST_PARAM: "{5,0}"
Would yield:
ok: [localhost] =>
msg: !!set
0: null
5: null
And since 5
and 0
are the keys of the set, the set get sorted by keys.
You can force it to be represented as a string, though, with the string
filter of Jinja.
The task:
- debug:
msg: "{{ LOCAL_HIGHEST_PARAM }}"
vars:
GLOBAL_HIGHEST_PARAM: "{5,0}"
LOCAL_HIGHEST_PARAM: "{{ GLOBAL_HIGHEST_PARAM | string }}"
Will give you the expected
ok: [localhost] =>
msg: '{5,0}'
Note that it does work in a task name because tasks names can only be string, so it is implicitly casted as a string, while it might not be, in other cases, without an explicit string
filter.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论