如何遍历Ansible清单中定义的用户变量列表执行命令?
问题:Ansible遍历主机用户列表执行grep命令失败
问题详情
现有INI格式的Ansible清单:
hostname1 users=user1,user2,user3 hostname2 users=user1,user2
需要编写Playbook,遍历每个主机的users变量列表,为每个用户执行grep username /etc/passwd命令。当前编写的Playbook如下:
--- - name: Grep shadow entries for users hosts: all tasks: - name: Get shadow entry for each user shell: "grep {{ item }} /etc/shadow" register: shadow_entry with_items: "{{ hostvars[inventory_hostname].users }}" - name: Print shadow entry debug: msg: "{{ shadow_entry.results }}"
实际执行时并未逐个用户循环,而是执行了grep [user1,user2,user3] /etc/passwd(将整个字符串作为参数)。尝试过多种清单变量写法:
hostname1 users=["user1","user2","user3"] hostname1 users='["user1","user2","user3"]' hostname1 users="user1","user2","user3"
均无法解决问题。
解决方案
问题核心是:INI清单里的users默认被识别为字符串,而非列表,导致with_items无法正确遍历每个用户。以下是三种可行解决方法:
方法1:在Playbook中把字符串转成列表
无需修改清单,直接用split(',')过滤器将逗号分隔的字符串拆分为列表:
--- - name: Grep passwd entries for users hosts: all tasks: - name: Get passwd entry for each user shell: "grep {{ item }} /etc/passwd" register: passwd_entry with_items: "{{ users.split(',') }}" - name: Print each user's passwd entry debug: msg: "User {{ item.item }}: {{ item.stdout }}" with_items: "{{ passwd_entry.results }}"
这个方法兼容原清单格式,同时优化了debug输出,更清晰展示每个用户的结果。
方法2:修改INI清单为数组格式
在INI清单中,重复定义同一个变量键,Ansible会自动合并为列表:
hostname1 users=user1 users=user2 users=user3 hostname2 users=user1 users=user2
此时Playbook无需修改,直接用with_items: "{{ users }}"即可正常遍历每个用户。
方法3:改用YAML格式清单(推荐)
YAML格式对列表的定义更直观,不易出错,创建inventory.yaml:
all: hosts: hostname1: users: - user1 - user2 - user3 hostname2: users: - user1 - user2
使用该清单时,原Playbook的with_items: "{{ users }}"就能直接正常工作,无需额外处理。
内容的提问来源于stack exchange,提问作者Cat Hariss
相关产品推荐
相关产品推荐

