[英]Ansible - Filter Dictionary Values
I have gathered the list of all users using getent_module :我已经使用getent_module收集了所有用户的列表:
- name: Get user info
getent:
database: passed
This returns this variable as getent_passwd, a dictionary like this:这会将这个变量作为 getent_passwd 返回,一个像这样的字典:
{
"uuidd": [
"x",
"107",
"112",
"",
"/run/uuidd",
"/usr/sbin/nologin"
],
"www-data": [
"x",
"33",
"33",
"www-data",
"/var/www",
"/usr/sbin/nologin"
]
}
I'm trying to return an array of users, including some specific users, finding the key of item.value in which "/home" is a part of one of the value array items and "nologin" is not.我试图返回一组用户,包括一些特定的用户,找到 item.value 的键,其中“/home”是值数组项之一的一部分,而“nologin”不是。 This is the code I have written so far, but it is not correct.这是我到目前为止写的代码,但它不正确。
- 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) }}"
How should I change my conditions to get the expected result?我应该如何改变我的条件以获得预期的结果?
As you understood correctly, since pattern/regex matching works on strings and not on items of list, when
condition won't work.正如您正确理解的那样,由于模式/正则表达式匹配适用于字符串而不适用于列表项when
因此条件不起作用。 While matching items from a list, we need to match the complete item, ie在匹配列表中的项目时,我们需要匹配完整的项目,即
when:
- "'/home/someuser' in item.value"
- "'/usr/sbin/nologin' not in item.value"
Typically, the $HOME
path in Linux is /home/$USER
.通常,Linux 中的$HOME
路径是/home/$USER
。 The resulting getent_passwd
contains the username in item.key
.生成的getent_passwd
包含item.key
中的用户名。 Which means that we can use /home/{{ item.key }}
to match in item.value
.这意味着我们可以使用/home/{{ item.key }}
来匹配item.value
。
A task such as below should do the job:像下面这样的任务应该可以完成这项工作:
- 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) }}"
The other approach could be to actually join
the item.value
to get a string similar to the one in /etc/passwd
so that we can do text search such as: '/home' search in (item.value)
.另一种方法可能是实际join
item.value
以获取与/etc/passwd
中的字符串相似的字符串,以便我们可以进行文本搜索,例如: '/home' search in (item.value)
。
Example:例子:
# 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) }}"
Extension of the other answer with additional check to exclude system users:通过附加检查扩展其他答案以排除系统用户:
- name: save users with actual login
set_fact:
actual_users: "{{ actual_users | default([]) + [ item.key ] }}"
when:
- "item.value[1] | int >= 1000"
- "'/home' in item.value[4]"
- "'nologin' not in item.value[5]"
loop: "{{ lookup('dict', getent_passwd) }}"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.