You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Ansible Playbook生成多行CSV报错:dict对象无stdout_lines属性

解决Ansible生成用户CSV文件的问题

问题分析

你遇到的核心问题有两个:

  1. getent模块的返回结果没有stdout_lines属性(这个属性仅属于shell/command类模块),所以用with_items: "{{ user_list.stdout_lines }}"会报错。
  2. 原任务直接将所有用户作为一个列表写入单行,没有实现每个用户单独占一行的需求。

修正后的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 16:07:44