使用set_fact追加值时出现Ansible变量未定义语法错误
解决Ansible中set_fact追加变量时的未定义错误
我来帮你搞定这个问题!你遇到的报错核心原因很明确:第一次尝试给recdb赋值时,这个变量还没有被初始化,Ansible没办法对一个未定义的变量执行加法操作,所以才会抛出'recdb' is undefined的错误。
咱们直接看修复后的Playbook,再一步步解释关键点:
- name: "Collecting information" shell: "ls -l {{ item }}" register: APP with_fileglob: - "{{ playbook_dir }}/tmpfiles/*" - set_fact: fdet: "{{ APP.results|map(attribute='stdout')|list }}" # 关键步骤:先初始化recdb为空字符串,避免未定义错误 - set_fact: recdb: "" # 现在可以安全地追加inventory_hostname了 - set_fact: recdb: "{{ recdb }} {{ inventory_hostname }}" # 循环追加fdet中的每个输出条目 - set_fact: recdb: "{{ recdb }} {{ item }}" loop: "{{ fdet }}" - debug: msg: "SOLUTION FOR TRICKY {{ recdb }}"
核心修复点说明:
- 初始化变量:在第一次使用
recdb之前,必须给它一个初始值(这里用空字符串""),这样后续的字符串拼接操作才有合法的基础。 - 空格分隔:拼接时手动加上空格
{{ recdb }} {{ inventory_hostname }},确保最终输出的各个部分用空格分隔,和你期望的格式一致。
更简洁的写法(可选)
其实你可以不用多次调用set_fact和循环,直接用Ansible的过滤器一次性完成拼接,代码更简洁高效:
- name: "Collecting information" shell: "ls -l {{ item }}" register: APP with_fileglob: - "{{ playbook_dir }}/tmpfiles/*" - set_fact: fdet: "{{ APP.results|map(attribute='stdout')|list }}" # 一步完成主机名和所有文件信息的拼接 - set_fact: recdb: "{{ inventory_hostname }} {{ fdet|join(' ') }}" - debug: msg: "SOLUTION FOR TRICKY {{ recdb }}"
这个写法用join(' ')把fdet列表中的所有元素用空格连接,再和inventory_hostname拼接,最终效果和之前的循环写法完全一致,但减少了任务数量,执行效率更高。
内容的提问来源于stack exchange,提问作者Ashar
相关产品推荐
相关产品推荐

