Мне нужен метод, позволяющий остановить цикл в Ansible, например break
в операторе for
в C++ или Bash. Например, мне нужно последнее значение перед циклическим сканированием до 0.
default/main.yml
---
os_vars:
- 8
- 10
- 15
- 6
- 0
- 7
- 25
tasks/main.yml
- name: Debug variables
ansible.builtin.set_fact:
a: "{{ item }}"
loop: "{{ os_vars }}"
when: item > 0
И вывод
TASK [test_role : Debug variables] *********************************************
ok: [localhost] => (item=8)
ok: [localhost] => (item=10)
ok: [localhost] => (item=15)
ok: [localhost] => (item=6)
skipping: [localhost] => (item=0)
ok: [localhost] => (item=7)
ok: [localhost] => (item=25)
Я знаю, что могу установить другую переменную bool для управления циклом, которому не назначены следующие элементы, но мне также нужно сэкономить время, чтобы повысить производительность этой книги, поскольку иногда тело цикла может представлять собой огромный массив, а мы этого не делаем. необходимо проверить следующие элементы, когда какое-либо условие соответствует...
Пожалуйста, поделитесь своими комментариями. Заранее спасибо.
Вопрос: «Я знаю, что могу установить другую переменную bool для управления циклом, не присваивающим следующие элементы»
Правильно, как есть
Похожие вопросы и ответы
и многое другое...
Вопрос: «Мне нужен метод, позволяющий остановить цикл в Ansible, например break
в операторе for
в C++ или Bash».
Такого нет. Вы не можете разорвать цикл, вы можете только реализовать пропуск.
Это потому, что
Что нужно знать о программировании с использованием Ansible
Ansible не является языком: Если Ansible не является языком программирования, то что это? Ansible — это инструмент, написанный на Python, который использует декларативный язык разметки YAML для описания желаемого состояния устройств и конфигурации. ... Вы объявляете аспекты, которые хотите настроить на целевом устройстве, например, существование файла или каталога, установлен пакет, запущена служба и т. д.
Думайте декларативно: Ansible по своей сути является движком желаемого состояния. Если вы пытаетесь «написать код» в своих пьесах и ролях, вы обрекаете себя на неудачу. Наши сборники пьес на основе YAML никогда не предназначались для программирования.
Вопрос: «Мне также нужно сэкономить время, чтобы повысить производительность этой книги, поскольку иногда тело цикла может представлять собой огромный массив, и нам не нужно проверять следующие элементы, когда какое-то условие соответствует».
Если вам нравится или вам необходимо реализовать такое поведение, возможно, вам придется написать что-нибудь самостоятельно. Смотрите на примере Стоит ли разрабатывать модуль? и Разработка модулей.
Другой подход может заключаться в предварительной обработке структуры данных, os_vars
списке, чтобы иметь возможность использовать ее только после этого.
os_vars:
- 8
- 10
- 15
- 6
чтобы обеспечить цикл. Тогда вообще не потребуется никакого разрыва или конструкции if then else.
Дальнейшее чтение
Основываясь на приведенных комментариях и, насколько я понял, вариант использования, возможный подход к решению без BREAK
, when:
или какой-либо конструкции IF
, THEN
, ELSE
.
Минимальный пример сборника сценариев
---
- hosts: localhost
become: false
gather_facts: false
vars:
os_vars:
- 8
- 10
- 15
- 6
- 0
- 7
- 25
tasks:
- name: Loop up to idx
debug:
msg: "{{ item }}"
loop: "{{ os_vars[:idx | int] }}"
loop_control:
extended: true
label: "{{ ansible_loop.index }}"
# Get index of zero (0) value
vars:
idx: "{{ os_vars.index(os_vars | min) }}"
приведет к выводу
TASK [Loop up to idx] ********
ok: [localhost] => (item=1) =>
msg: 8
ok: [localhost] => (item=2) =>
msg: 10
ok: [localhost] => (item=3) =>
msg: 15
ok: [localhost] => (item=4) =>
msg: 6
На основе
Верно. Но я хотел бы еще раз порекомендовать вам тщательно продумать вариант использования. Возможно, вы сможете Удалить пункты из списка раньше. Чтобы помочь в этом, нам понадобится еще один вопрос с более подробным описанием вашей структуры данных и того, чего вы пытаетесь достичь, вместо того, чтобы сосредоточиться на возможном решении.
Кроме того, должна быть возможность реализовать пользовательский фильтр на основе Как удалить элемент из списка по индексу или просто использовать Нотацию фрагментов Python для доступа к элементам списка. Найдите индекс 0
и выполните цикл только по списку до этого индекса.
Еще раз спасибо... Ваш комментарий очень поучителен... Посмотрю, подумаю... :)
Пожалуйста, найдите возможный подход к решению на основе приложенных комментариев.
Большое спасибо. Используя ваш пример кода, я переписываю свою книгу пьес с ограниченным массивом, например -- with_items: "{{ checkfile_lines[(table_head_index|int):(table_close_index|int)] }}".. И это работает нормально. Время работы сократилось с 5м до 20с....еще раз спасибо.
Большое спасибо за ваш подробный ответ. Теперь мы видим — кто-то хотел добавить эту функцию из 2019 года, но она до сих пор недоступна... :(