当元素包含一个字符串时,我正试图在Jinja2中过滤ansible中的列表,但是Jinja文档似乎不够清晰,我无法弄明白。
这是我到目前为止所做的:
- name: run script
command: /usr/tmp/run_script.py
register: script_results
- name: display run info
debug:
var: "{{script_results.stdout_lines | select(\"'running script' in script_results.stdout_lines\") }}"
但我得到的只是错误:
"<generator object _select_or_reject at 0x13851e0>": "VARIABLE IS NOT DEFINED!"
例如,如果stdout_lines
包含["apples","running script one","oranges","running script two"]
,我想打印
running script one
running script two
他们有documentation for select和documentation for built-in-tests,但他们没有显示“in”测试,我不知道它们在这个ansible变量的上下文中是如何工作的。
我试着像这样解决它:
- name: display run info
debug:
var: item
with_items: "{{script_results.stdout_lines}}"
when: "'running script' in item"
但是对于没有通过测试的每一行显示“跳过”...有点击败目的!
答案 0 :(得分:14)
select
过滤器需要另一个过滤器。就像在文档odd
中一样,它只返回列表中的奇数元素。要与select
合并的过滤器为equalto
。
现在就是这样。 Ansible捆绑了一个非常旧版本的Jinja2,它只是不包含equalto
过滤器。是的,除非你想过滤奇数元素,否则它会变得无用。 (历史上没有人想要......)
此外,我还无法在Ansible 2中使自定义过滤器插件工作。所以你几乎不得不一起破解丑陋的东西。
helloV已经显示了一个选项。这是另一个想法:
- name: run script
shell: /usr/tmp/run_script.py | grep "running script"
register: script_results
更新
我最近发现你可以使用match
(不是标准的Jinja2过滤器,但是由Ansible添加)和select
。这是eualto
过滤器的一个很好的替代品,你可以使用正则表达式。这应该有效:
{{ script_results.stdout_lines | select("match", ".*running script.*") }}
答案 1 :(得分:4)
我知道可能有多种方法可以做到这一点。这对你有用吗?
- debug: var={{item}}
when: item.find('running script') > -1
with_items: script_results.stdout_lines
答案 2 :(得分:0)
我最终编写了一个python脚本来完成它,因为我无法获得ansible或者古代jinja2来制作剪辑。
Ansible任务:
- name: gather run info
command: "{{role_path}}/files/print_results.py {{script_results.stdout_lines}}"
register: script_print_results
delegate_to: 127.0.0.1
run_once: true
- name: display run info
debug:
var: script_print_results.stdout_lines
delegate_to: 127.0.0.1
run_once: true
Python脚本:
for result_line in sys.argv[1:]:
if "running script:" in result_line:
print result_line[1:-1]
答案 3 :(得分:0)
您可以使用set_fact
构建新列表,并打印新列表的元素。
- hosts: localhost
gather_facts: false
vars:
script_stdout_lines:
- apples
- running script one
- oranges
- running script two
tasks:
- set_fact:
new_list: "{{ new_list | default([]) + [item] }}"
with_items: "{{ script_stdout_lines }}"
when: '"running script" in item'
- debug: var=new_list
结果:
TASK [set_fact] *********************************************************************************************************************
skipping: [localhost] => (item=apples)
ok: [localhost] => (item=running script one)
skipping: [localhost] => (item=oranges)
ok: [localhost] => (item=running script two)
TASK [debug] ************************************************************************************************************************
ok: [localhost] => {
"new_list": [
"running script one",
"running script two"
]
}
它在skipping
操作期间打印set_fact
,但最后它提供了一个仅包含匹配项目的新列表。