Как извлечь или зафиксировать значение из stdout_lines плейбука Ansible?

Мне нужна помощь, чтобы извлечь или зафиксировать значение свободных МБ из stdout_lines выполнения плейбука Ansible и использовать это значение в качестве критерия для дальнейшего продвижения по плейбуку.

Результат моей задачи:

ok: [Host1] => {
    "changed": false,
    "invocation": {
        "module_args": {
            "commands": [
                "show file systems | inc flash:"
            ],
            "interval": 1,
            "match": "all",
            "retries": 10,
            "wait_for": null
        }
    },
    "stdout": [
        "*     1707192   (1.6 GB)        603744 (589.6 MB)      flash     rw  flash:"
    ],
    "stdout_lines": [
        [
            "*     1707192   (1.6 GB)        603744 (589.6 MB)      flash     rw  flash:"
        ]
    ]
}

Я пытался использовать

- set_fact:
    my_var: "{{ disk_space.stdout_lines | regex_findall('\\b([0-9]{1,4}\\.\\d+)\\s+MB.*flash:$') }}"

Но я всегда получаю пустой вывод:

ok: [Host1] => {
    "ansible_facts": {
        "my_var": []
    },
    "changed": false
}

Я хотел бы получить значение 589.6 из вывода и присвоить его переменной, которая будет использоваться в моей дальнейшей игре.

Можете ли вы предоставить свою задачу, а также описание удаленной системы? Возможно, уже существуют варианты получения вывода более простым или отформатированным способом или даже специальные модули.

U880D 23.07.2024 13:59
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Просто отвечаю на часть вопроса, связанную с регулярным выражением.

Выражение, написанное так

\\b([0-9]{1,4}\\.\\d+)\\s+MB.*flash:$

и анализируется как

\b([0-9]{1,4}\.\d+)\s+MB.*flash:$

означает «строка должна заканчиваться на flash:, но она заканчивается как на flash:"

Решение простое — добавьте символ непосредственно перед знаком доллара.

\b([0-9]{1,4}\.\d+)\s+MB.*flash:"$

Не уверен, следует ли это экранировать или закодировать каким-либо конкретным способом в вашем случае.

Привет, Сэм! Большое спасибо, что обратили на это внимание. Я внес предложенное вами изменение, но все равно на выходе выдает пустой список. - set_fact: my_var: "{{ disk_space.stdout_lines | regex_findall('\\b([0-9]{1,4}\\.\\d+)\\s+MB.*flash:\"$') }}" Вывод: ok: [ALM-DUT-MGT-P01-05] => { "ansible_facts": { "my_var": [] }, "changed": false }

PraveenPrasannan 23.07.2024 23:23
Ответ принят как подходящий

Другой возможный подход показан в следующем минимальном примере сборника сценариев.

---
- name: Cisco 'show file systems'
  hosts: localhost
  become: false
  gather_facts: false

  vars:

    disk_space:
      stdout: "*     1707192   (1.6 GB)        603744 (589.6 MB)      flash     rw  flash:"
      stdout_lines:
        - "*     1707192   (1.6 GB)        603744 (589.6 MB)      flash     rw  flash:"

  tasks:

  - name: Show stdout with data cleansing
    debug:
      msg: "{{ disk_space.stdout | regex_replace('  *', ' ') }}"

  - name: Show value of 4th column in KB
    debug:
      msg: "{{ ( disk_space.stdout | regex_replace('  *', ' ') | split(' ') )[4] }} KB"

  - name: Show value of 4th column in MB
    debug:
      msg: "{{ ( disk_space.stdout | regex_replace('  *', ' ') | split(' ') )[4] | int / 1024 }} MB"

что приводит к выходу

TASK [Show stdout with data cleansing] **********************
ok: [localhost] =>
  msg: '* 1707192 (1.6 GB) 603744 (589.6 MB) flash rw flash:'

TASK [Show value of 4th column in KB] ***********************
ok: [localhost] =>
  msg: 603744 KB

TASK [Show value of 4th column in MB] ***********************
ok: [localhost] =>
  msg: 589.59375 MB

Или даже

  - name: Show value of 5th column after cleansing
    debug:
      msg: "{{ ( result.stdout | regex_replace('  *', ' ') | replace('(', '') | replace(')', '') | split(' ') )[5] }}"

с результатом

TASK [Show value of 5th column] ****************************
ok: [localhost] =>
  msg: '589.6'

Привет @U880D! Большое спасибо за помощь!! Это сработало, и я получил точное значение. Этот метод определенно можно использовать и в других случаях. Однако я все еще пытался извлечь значение, используя regex_findall. Спасибо !!

PraveenPrasannan 23.07.2024 23:27

Другие вопросы по теме