Ansible中如何获取压缩包解压后的顶层目录名并保存为变量
Ansible 动态获取解压后未知版本号目录的实现方案
核心逻辑:解压完成后通过文件查找模块匹配目标路径下符合命名规则的目录,按修改时间筛选出最新解压的目录,注册为变量后即可供全playbook后续任务调用,不需要提前预知版本号。
可直接复用的Playbook片段
- 先执行解压任务,指定固定的解压父目录即可,不需要关心压缩包内的顶层目录名:
- name: 解压下载好的最新安装包 ansible.builtin.unarchive: src: /tmp/file-latest.zip dest: /opt/your_target_path/ # 压缩包在远程节点就设为yes,从本地Ansible主控端传过去就设为no remote_src: yes
- 查找解压路径下所有符合命名规则的目录,将查找结果注册为临时变量:
- name: 匹配所有file-开头的版本目录 ansible.builtin.find: paths: /opt/your_target_path/ # 正则匹配file-开头的目录,可根据实际命名规则调整 patterns: 'file-*' file_type: directory register: extracted_dirs
- 对查找结果按修改时间倒序排序,取最新的(也就是刚解压生成的)目录,提取为可复用的全局变量:
- name: 生成版本目录、版本号全局变量 ansible.builtin.set_fact: # 版本目录全路径,格式类似/opt/your_target_path/file-1.2.20 app_dir_path: "{{ extracted_dirs.files | sort(attribute='mtime', reverse=true) | first | json_query('path') }}" # 纯版本号,格式类似1.2.20,不需要可以不写 app_version: "{{ app_dir_path | basename | regex_replace('^file-', '') }}"
后续所有任务直接引用{{ app_dir_path }}、{{ app_version }}两个变量即可,示例:
- name: 拷贝配置文件到版本目录 ansible.builtin.template: src: app_config.j2 dest: "{{ app_dir_path }}/conf/config.ini"
注意事项
- 该逻辑兼容目录下存在旧版本的场景:刚解压的目录修改时间一定是最新的,排序后取第一个不会误选旧版本目录
- 如果担心匹配到无关目录,可以把
patterns参数的匹配规则收窄,比如用'file-[0-9]*\.[0-9]*\.[0-9]*',仅匹配file-数字.数字.数字格式的标准版本目录 - 调试阶段可以加一个debug任务验证取值是否正确:
- name: 打印变量验证结果 ansible.builtin.debug: msg: "当前解压得到的版本目录为:{{ app_dir_path }},对应版本号:{{ app_version }}"
备选方案:如果解压路径下存在大量同前缀目录、无法通过修改时间判断,可以在解压前直接读取压缩包的目录结构拿到顶层目录名,执行命令
unzip -l /tmp/file-latest.zip | awk '{print $4}' | grep -E '^file-[0-9.]+/$' | head -n1 | tr -d '/'注册为变量即可。该方法需要远程节点预装unzip工具,优先推荐前面的原生模块方案,无额外命令依赖。
内容的提问来源于stack exchange,提问作者Stigla7
相关产品推荐
相关产品推荐

