Ansible YAML中文件存在时设置变量的实现问题
Ansible:仅当文件存在时设置变量的正确方式
我来帮你搞定这个Ansible变量设置的问题!你之前的写法无效是因为vars关键字(不管是play级定义还是vars模块)是在play解析阶段就被处理的,没法和when条件配合实现运行时的动态变量赋值。下面给你两种靠谱的解决方案:
方法一:用set_fact配合stat任务(推荐,适用于远程主机文件判断)
这是最常用的方式,先通过stat任务检查远程主机上的文件是否存在,再用set_fact在满足条件时设置变量:
- hosts: all tasks: # 第一步:检查目标文件是否存在,将结果注册到result变量 - stat: path: '{{ srch_path_new }}/bin/run' register: result # 第二步:仅当文件存在时,设置srch_path变量 - set_fact: srch_path: "{{ srch_path_new }}" when: result.stat.exists
为什么这个能生效?
set_fact是Ansible专门用来在任务执行阶段动态设置变量的模块,它完全支持when条件判断。只有当远程主机上的{{ srch_path_new }}/bin/run文件存在时,才会把srch_path赋值为srch_path_new;如果文件不存在,这个变量不会被设置(如果之前有默认值则保持默认)。
方法二:用Jinja2条件表达式直接定义变量(仅适用于控制节点文件判断)
如果你要判断的是控制节点本地的文件,可以直接在变量定义时用Jinja2的三元表达式配合lookup('stat')完成,不需要单独的任务:
- hosts: all vars: # 直接通过lookup检查文件是否存在,用三元表达式赋值 srch_path: "{{ srch_path_new if (lookup('stat', srch_path_new ~ '/bin/run', get_checksum=False)).exists else '' }}" tasks: # 后续任务可以直接使用srch_path变量 - debug: msg: "srch_path is {{ srch_path }}"
注意事项
这种方式的局限性在于lookup('stat')是在控制节点执行的,所以如果你的srch_path_new是远程主机上的路径,这种方法就不适用了——它会检查控制节点上的文件,而不是目标主机的。
内容的提问来源于stack exchange,提问作者isoman
相关产品推荐
相关产品推荐

