使用Ansible Playbook生成多行CSV报错:dict对象无stdout_lines属性
解决Ansible生成用户CSV文件的问题
问题分析
你遇到的核心问题有两个:
getent模块的返回结果没有stdout_lines属性(这个属性仅属于shell/command类模块),所以用with_items: "{{ user_list.stdout_lines }}"会报错。- 原任务直接将所有用户作为一个列表写入单行,没有实现每个用户单独占一行的需求。
修正后的Playbook
--- - hosts: all gather_facts: true vars: report_path: /tmp/rhel_user_list.csv tasks: - name: 创建CSV表头文件 shell: echo 'Hostname,User' > {{ report_path }} args: chdir: /tmp run_once: true - name: 获取系统用户列表 getent: database: passwd register: user_list - name: 逐行写入主机名与用户 lineinfile: line: "{{ ansible_hostname }},{{ item }}" path: "{{ report_path }}" insertafter: EOF loop: "{{ ansible_facts.getent_passwd.keys() }}"
关键修改说明
- 移除错误的
stdout_lines引用:getent模块执行后,用户列表存储在ansible_facts.getent_passwd字典中,通过keys()方法可以获取所有用户名,直接用loop: "{{ ansible_facts.getent_passwd.keys() }}"遍历每个用户。 - 单行写入单个用户:将
line的内容从{{ansible_hostname}}, {{ getent_passwd.keys() | list }}改为{{ ansible_hostname }},{{ item }},这样每次循环都会生成一行单独的主机名+用户记录。 - 修正表头:将原表头
Hostname, User List改为Hostname,User,与你期望的输出格式匹配。 - 明确变量定义:将
report_path作为变量定义在vars段,提升可读性和可维护性。
可选优化:过滤普通用户
如果只需要导出UID≥1000的普通用户,可以修改循环条件,通过json_query过滤:
- name: 逐行写入主机名与普通用户 lineinfile: line: "{{ ansible_hostname }},{{ item.key }}" path: "{{ report_path }}" insertafter: EOF loop: "{{ ansible_facts.getent_passwd | dict2items | json_query('[?value[1] >= `1000`]') }}"
内容的提问来源于stack exchange,提问作者gbahrman
相关产品推荐
相关产品推荐

