#ansible #filtering #ansible-module
Вопрос:
Я собрал список всех пользователей с помощью getent_module:
- name: Get user info
getent:
database: passed
Это возвращает эту переменную как getent_passwd, словарь, подобный этому:
{
"uuidd": [
"x",
"107",
"112",
"",
"/run/uuidd",
"/usr/sbin/nologin"
],
"www-data": [
"x",
"33",
"33",
"www-data",
"/var/www",
"/usr/sbin/nologin"
]
}
Я пытаюсь вернуть массив пользователей, включая некоторых конкретных пользователей, найдя ключ item.value, в котором «/home» является частью одного из элементов массива значений, а «nologin» — нет.
Это код, который я написал до сих пор, но он неверен.
- name: style the user list
set_fact:
my_users: "{{ item.key | default([]) }}"
when:
- "'nologin' not in (item.value)"
- "'/home' search in (item.value)"
loop: "{{ lookup('dict', getent_passwd) }}"
Как я должен изменить свои условия, чтобы получить ожидаемый результат?
Ответ №1:
Как вы правильно поняли, поскольку сопоставление шаблонов/регулярных выражений работает со строками, а не с элементами списка, when
условие не будет работать. При сопоставлении элементов из списка нам нужно сопоставить полный элемент, т. е.
when:
- "'/home/someuser' in item.value"
- "'/usr/sbin/nologin' not in item.value"
Как правило, $HOME
путь в Linux таков /home/$USER
. Полученный результат getent_passwd
содержит имя пользователя в item.key
. А это значит, что мы можем использовать /home/{{ item.key }}
их для сопоставления item.value
.
Задача, подобная приведенной ниже, должна выполнить эту работу:
- name: save users with actual login
set_fact:
my_users: "{{ my_users | default([]) [ item.key ] }}"
when:
- "'/home/' ~ item.key in item.value"
- "'/usr/sbin/nologin' not in item.value"
loop: "{{ lookup('dict', getent_passwd) }}"
Другой подход может заключаться в том, чтобы на самом деле join
item.value
получить строку, аналогичную той, в /etc/passwd
которой мы можем выполнить текстовый поиск, например: '/home' search in (item.value)
.
Пример:
# item.value | join(':') is the same as each line of '/etc/passwd'
- name: save users with actual login
set_fact:
my_users: "{{ my_users | default([]) [ item.key ] }}"
when:
- "'/home' in item.value | join(':')"
- "'nologin' not in item.value | join(':')"
loop: "{{ lookup('dict', getent_passwd) }}"