Ansible使用set_fact与条件语句报错:无法访问hostname属性
Ansible报错 'AnsibleUnsafeText object' has no attribute 'hostname' 解决及需求实现
报错核心原因
这个错误是因为你尝试访问字符串类型变量的字典属性(如.hostname),但该变量实际是Ansible包装的字符串类型AnsibleUnsafeText,并非字典/对象结构,因此找不到对应的属性。
完整实现方案(符合你的需求)
以下是修正后的Playbook代码,实现「Composer运行则显示其版本,否则显示Fleet-Manager版本,均未运行则提示未部署」的逻辑:
1. 获取服务状态与版本信息
- name: 收集系统服务状态 service_facts: - name: 查询Composer版本(仅当服务运行时) command: composer --version register: composer_version ignore_errors: true when: "'composer.service' in services and services['composer.service'].state == 'running'" - name: 查询Fleet-Manager版本(仅当服务运行时) command: fleet-manager --version register: fleet_manager_version ignore_errors: true when: "'fleet-manager.service' in services and services['fleet-manager.service'].state == 'running'"
2. 正确设置stack_version变量
使用Jinja2条件判断赋值,避免字符串变量的错误属性调用:
- name: 设置stack_version set_fact: stack_version: | {% if composer_version is succeeded %} Composer版本: {{ composer_version.stdout.split()[-1] }} {% elif fleet_manager_version is succeeded %} Fleet-Manager版本: {{ fleet_manager_version.stdout.split()[-1] }} {% else %} 未部署Composer或Fleet-Manager服务 {% endif %}
3. 组装报告并写入文件
- name: 组装服务器报告 set_fact: server_report: | 服务器主机名: {{ ansible_hostname }} 服务状态报告: {{ stack_version }} - name: 写入报告到文件 shell: echo "{{ server_report }}" > /var/log/server_report.txt
关键修正说明
- 禁止对字符串变量使用
.hostname:比如之前错误的{{ stack_version.hostname }},stack_version是字符串,无法调用字典属性,直接用ansible_hostname内置变量获取主机名即可。 - 变量类型校验:确保条件判断中引用的是正确的变量类型,比如
composer_version是command模块返回的字典对象,用is succeeded判断命令执行状态,而非把它当字符串处理。 - 容错处理:添加
ignore_errors: true,避免服务未运行时的命令报错中断Playbook执行。
内容的提问来源于stack exchange,提问作者Ankur Agarwal
相关产品推荐
相关产品推荐

