web-dev-qa-db-ja.com

文字列を使用したJinja2フィルターリストにはテストが含まれています

要素に文字列が含まれている場合、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

selectのドキュメント組み込みテストのドキュメント がありますが、「in」テストは表示されず、どのように動作するのかわかりませんこのansible変数のコンテキスト。

私はそれを次のように解決しようとしました:

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

しかし、テストに合格しなかったすべての行の「スキップ」が表示されます...目的をやや破ってしまいます!

10
CorayThan

selectフィルターは別のフィルターを取ります。ドキュメントのoddのように、リストの奇数の要素のみを返します。 selectと組み合わせるフィルターはequaltoです。

今ここにあるものです。 Ansibleには、equaltoフィルターが含まれていない非常に古いバージョンのJinja2がバンドルされています。はい、奇数の要素をフィルターにかけたくない限り、それは役に立たなくなります。 (歴史上、誰も望んでいなかった...)

さらに、Ansible 2ではカスタムフィルタープラグインを機能させることができませんでした。そのため、何か醜いものを一緒にハックする必要がかなりあります。

helloVはすでに1つのオプションを示しています。ここに別のアイデアがあります:

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

更新:

最近、matchselectと併用できることを発見しました(標準のJinja2フィルターではなく、Ansibleによって追加されました)。これはeualtoフィルターの優れた代替であり、正規表現を使用できます。これはうまくいくはずです:

{{ script_results.stdout_lines | select("match", ".*running script.*") }}
15
udondan

これには複数の方法があることを理解しています。これでうまくいきますか?

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

pythonそれを行うためのスクリプトを書いてしまいました。なぜなら、私はansibleやAncient-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]
1
CorayThan

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"
    ]
}

set_fact操作中にskippingを出力しますが、最後に、一致する項目のみを含む新しいリストを提供します。

1
Akif