Ansible - 过滤字典值
Ansible - Filter Dictionary Values
我已经收集了所有使用 getent_module 的用户列表:
- name: Get user info
getent:
database: passed
This returns this variable as getent_passwd, a dictionary like this:
{
"uuidd": [
"x",
"107",
"112",
"",
"/run/uuidd",
"/usr/sbin/nologin"
],
"www-data": [
"x",
"33",
"33",
"www-data",
"/var/www",
"/usr/sbin/nologin"
]
}
我正在尝试 return 一组用户(包括一些特定用户)找到 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) }}"
我应该如何改变我的条件以获得预期的结果?
正如您正确理解的那样,由于 pattern/regex 匹配适用于字符串而不适用于列表项,因此 when
条件将不起作用。在匹配列表中的项目时,我们需要匹配完整的项目,即
when:
- "'/home/someuser' in item.value"
- "'/usr/sbin/nologin' not in item.value"
通常,Linux 中的 $HOME
路径是 /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) }}"
我已经收集了所有使用 getent_module 的用户列表:
- name: Get user info
getent:
database: passed
This returns this variable as getent_passwd, a dictionary like this:
{
"uuidd": [
"x",
"107",
"112",
"",
"/run/uuidd",
"/usr/sbin/nologin"
],
"www-data": [
"x",
"33",
"33",
"www-data",
"/var/www",
"/usr/sbin/nologin"
]
}
我正在尝试 return 一组用户(包括一些特定用户)找到 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) }}"
我应该如何改变我的条件以获得预期的结果?
正如您正确理解的那样,由于 pattern/regex 匹配适用于字符串而不适用于列表项,因此 when
条件将不起作用。在匹配列表中的项目时,我们需要匹配完整的项目,即
when:
- "'/home/someuser' in item.value"
- "'/usr/sbin/nologin' not in item.value"
通常,Linux 中的 $HOME
路径是 /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) }}"