2016-02-09 7 views
5

Ich versuche, eine Liste in Ansible in Jinja2 zu filtern, wenn die Elemente eine Zeichenfolge enthalten, aber die Jinja-Dokumentation scheint nicht klar genug zu sein, um es herauszufinden.Jinja2 Filterliste mit String enthält Test

Das ist, was ich bisher habe:

- 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\") }}" 

Aber alles, was ich bekommen, ist der Fehler:

"<generator object _select_or_reject at 0x13851e0>": "VARIABLE IS NOT DEFINED!" 

So zum Beispiel, wenn stdout_lines["apples","running script one","oranges","running script two"] enthält, möchte ich

drucken
running script one 
running script two 

Sie haben documentation for select und documentation for built-in-tests, aber sie zeigen nicht den "in" -Test an und ich weiß nicht, wie sie im Kontext dieser Variablen funktionieren.

habe ich versucht, es so zu lösen:

- name: display run info 
    debug: 
    var: item 
    with_items: "{{script_results.stdout_lines}}" 
    when: "'running script' in item" 

Aber das zeigt „Überspringen“ für jede Zeile, die den Test nicht passieren ... irgendwie den Zweck zu besiegen!

Antwort

4

Ich verstehe, dass es mehr als eine Möglichkeit gibt, dies zu tun. Wird das für dich funktionieren?

- debug: var={{item}} 
    when: item.find('running script') > -1 
    with_items: script_results.stdout_lines 
+0

Diese eine Zeile für jede druckt übersprungen Artikel, die leider den Zweck besiegt. – CorayThan

10

Der Filter select würde einen anderen Filter nehmen. Wie in der Dokumentation odd, die nur die ungeraden Elemente der Liste zurückgibt. Der Filter, den Sie mit select kombinieren möchten, ist equalto.

Jetzt ist hier die Sache. Ansible bündelt eine sehr alte Version von Jinja2, die einfach nicht den equalto Filter enthält. Ja, das macht es nutzlos, wenn Sie ungerade Elemente filtern wollen. (Was niemand jemals in der Geschichte wollte ...)

Außerdem konnte ich noch keine benutzerdefinierten Filter-Plugins in Ansible 2 arbeiten lassen. Sie sind also ziemlich gezwungen, etwas Hässliches zusammen zu hacken.

halloV zeigte bereits eine Option. Hier ist eine andere Idee:

- name: run script 
    shell: /usr/tmp/run_script.py | grep "running script" 
    register: script_results 

Update:

ich vor kurzem entdeckt, die Sie verwenden können match (kein Standard Jinja2 Filter aber hinzugefügt von ansible) zusammen mit select. Das ist ein guter Ersatz für den eualto Filter plus Sie können reguläre Ausdrücke verwenden. Dies sollte funktionieren:

{{ script_results.stdout_lines | select("match", ".*running script.*") }} 
+0

Ich hätte diese Lösung verwendet, aber ich verwende tatsächlich die volle Ausgabe des Skripts an anderer Stelle in meinem Spiel. Ich nehme an, dass ich vielleicht die script_results an grep übergeben und eine zweite Variable auf diese Weise registrieren konnte, aber ich entschied mich stattdessen für die direkte Python-Route. – CorayThan

+0

@CorayThan Ich aktualisierte meine Antwort. Ich habe jetzt einen guten Ersatz für den 'Equality'-Filter gefunden. – udondan

+0

Danke @ubondan das war genau das, was ich gesucht habe. Hat sich bei den neuesten Ansible-Releases irgendwas geändert? –

0

ich einen Python-Skript zu schreiben endete, es zu tun, weil ich nicht ansible oder ancient-jinja2 bekommen konnte den Schnitt zu machen.

ansible Aufgaben:

- 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-Skript:

for result_line in sys.argv[1:]: 
    if "running script:" in result_line: 
     print result_line[1:-1]