如何检查一个项目是否存在于 Ansible 数组中?
How to check whether an item is present in an Ansible array?
假设我有以下示例,将所有 git config
值存储在 Ansible 变量中:
- shell: git config --global --list
register: git_config_list
Ansible 将此命令的结果存储在 git_config_list
变量中,其中一项是 stdout_lines
,包含条目数组中命令的输出,例如
[
"user.name=Foo Bar",
"user.email=foo@example.com"
]
如何检查某个值是否已经设置,例如用于验证 user.name
是否有值?
有没有办法在数组上调用类似 contains
的东西,结合正则表达式,让我找到我要找的值?还是我必须遍历 stdout_lines
条目才能找到我要找的东西?
将不胜感激有关如何执行此类操作的示例。
理论上,这应该可以通过组合过滤器 match
and select
来实现。后者 returns 只有那些通过另一个过滤器的列表元素。然后你可以测试结果的长度。
理论上。我刚刚对其进行了测试,但无法正常工作。一般来说,select
(以及 reject
)过滤 returns 一个像 <generator object _select_or_reject at 0x10531bc80>
这样的字符串,即使使用简单的过滤器,比如文档中带有 odd
的例子。还没能找到解决办法。也许你有更多的成功。
尽管您可以简单地将您的列表 join
转换为一个字符串,然后使用 match
在该字符串中搜索。虽然它很丑,但它确实有效。
git_config_list.stdout_lines | join("|") | match("user.name=[^|]+")
简单 python in
就可以了,注意我使用 stdout
而不是 stdout_lines
:
- debug: git_config_list contains user.name
when: "'user.name=' in '{{git_config_list.stdout}}'"
总而言之,ansible
对编程来说太可怕了。尽量在 playbook 之外做尽可能多的事情,并且只在 playbook 内编写编排逻辑。以下是一些示例,您可以如何使用 git
的 --get
选项。
- hosts: localhost
tags: so
gather_facts: False
tasks:
- shell: git config --global --get user.name
register: g
changed_when: False
failed_when: False
- debug: msg="config has user.name"
when: "0 == {{g.rc}}"
- hosts: localhost
tags: so
gather_facts: False
tasks:
- name: assert user.name is set
shell: git config --global --get user.name
changed_when: False
# git config --global --unset user.name
# ansible pb.yml -t so
# git config --global --add user.name 'Kashyap Bhatt'
# ansible pb.yml -t so
与select匹配(扩展udondan的答案):
git_config_list.stdout_lines | select('match', 'user\.name=.+') | list
假设我有以下示例,将所有 git config
值存储在 Ansible 变量中:
- shell: git config --global --list
register: git_config_list
Ansible 将此命令的结果存储在 git_config_list
变量中,其中一项是 stdout_lines
,包含条目数组中命令的输出,例如
[
"user.name=Foo Bar",
"user.email=foo@example.com"
]
如何检查某个值是否已经设置,例如用于验证 user.name
是否有值?
有没有办法在数组上调用类似 contains
的东西,结合正则表达式,让我找到我要找的值?还是我必须遍历 stdout_lines
条目才能找到我要找的东西?
将不胜感激有关如何执行此类操作的示例。
理论上,这应该可以通过组合过滤器 match
and select
来实现。后者 returns 只有那些通过另一个过滤器的列表元素。然后你可以测试结果的长度。
理论上。我刚刚对其进行了测试,但无法正常工作。一般来说,select
(以及 reject
)过滤 returns 一个像 <generator object _select_or_reject at 0x10531bc80>
这样的字符串,即使使用简单的过滤器,比如文档中带有 odd
的例子。还没能找到解决办法。也许你有更多的成功。
尽管您可以简单地将您的列表 join
转换为一个字符串,然后使用 match
在该字符串中搜索。虽然它很丑,但它确实有效。
git_config_list.stdout_lines | join("|") | match("user.name=[^|]+")
简单 python in
就可以了,注意我使用 stdout
而不是 stdout_lines
:
- debug: git_config_list contains user.name
when: "'user.name=' in '{{git_config_list.stdout}}'"
总而言之,ansible
对编程来说太可怕了。尽量在 playbook 之外做尽可能多的事情,并且只在 playbook 内编写编排逻辑。以下是一些示例,您可以如何使用 git
的 --get
选项。
- hosts: localhost
tags: so
gather_facts: False
tasks:
- shell: git config --global --get user.name
register: g
changed_when: False
failed_when: False
- debug: msg="config has user.name"
when: "0 == {{g.rc}}"
- hosts: localhost
tags: so
gather_facts: False
tasks:
- name: assert user.name is set
shell: git config --global --get user.name
changed_when: False
# git config --global --unset user.name
# ansible pb.yml -t so
# git config --global --add user.name 'Kashyap Bhatt'
# ansible pb.yml -t so
与select匹配(扩展udondan的答案):
git_config_list.stdout_lines | select('match', 'user\.name=.+') | list