要素に文字列が含まれている場合、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"
しかし、テストに合格しなかったすべての行の「スキップ」が表示されます...目的をやや破ってしまいます!
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
更新:
最近、match
をselect
と併用できることを発見しました(標準のJinja2フィルターではなく、Ansibleによって追加されました)。これはeualto
フィルターの優れた代替であり、正規表現を使用できます。これはうまくいくはずです:
{{ script_results.stdout_lines | select("match", ".*running script.*") }}
これには複数の方法があることを理解しています。これでうまくいきますか?
- debug: var={{item}}
when: item.find('running script') > -1
with_items: script_results.stdout_lines
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]
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
を出力しますが、最後に、一致する項目のみを含む新しいリストを提供します。