如何获取远程节点可用Python版本并注册最高版本?
解决Ansible获取多机Python版本并筛选最高版本的问题
问题分析
你当前的任务中,直接使用ansible_facts.packages['python*']是错误的——ansible_facts.packages是字典类型,键为精确的包名,不支持通配符直接匹配。需要通过过滤器筛选出所有Python相关的包,再提取版本信息。
解决方案Playbook
以下Playbook可以完成:收集所有Python版本(包管理器安装)、去重、排序并获取最高版本,同时输出每台机器的结果:
--- - name: 收集并处理Python版本信息 hosts: all gather_facts: false tasks: - name: 收集系统包事实 ansible.builtin.package_facts: manager: auto strategy: all - name: 提取包管理器中的所有Python版本 ansible.builtin.set_fact: python_pkg_versions: >- {{ ansible_facts.packages | dict2items # 筛选匹配Python解释器的包名,适配不同系统命名(如python2.7、python3、python38) | selectattr('key', 'match', '^python(\d+(\.\d+)*)?$|^python(\d)(\d)$') | map(attribute='value') | flatten | map(attribute='version') | list }} - name: 合并并去重所有Python版本(若需包含源码编译版本,可参考下方扩展) ansible.builtin.set_fact: python_all_versions: "{{ python_pkg_versions | unique }}" - name: 筛选最高Python版本 ansible.builtin.set_fact: python_latest_version: "{{ python_all_versions | version_sort | last }}" - name: 输出每台机器的Python版本信息 ansible.builtin.debug: msg: | 主机 {{ inventory_hostname }} 已安装的Python版本: {{ python_all_versions | join(', ') }} 最高可用版本: {{ python_latest_version }}
关键步骤解释
dict2items过滤器:将packages字典转换为键值对列表,方便后续筛选。selectattr正则匹配:筛选符合Python解释器命名规则的包(如python2.7、python3、python38),避免匹配python-pip这类依赖包。version_sort过滤器:按照版本号规则排序(而非字符串排序),确保3.8.10排在2.7.18之后。unique过滤器:去除重复的版本号(同一包可能被多次识别的情况)。
扩展:包含源码编译的Python版本
若机器上存在源码编译安装的Python(不在包管理器中),可添加以下任务补充收集:
- name: 查找系统中所有可执行的Python文件 ansible.builtin.command: find /usr/bin /usr/local/bin -name 'python*' -type f -executable | grep -v -E 'config|m$' register: python_executables changed_when: false - name: 提取可执行文件的版本号 ansible.builtin.command: "{{ item }} --version" register: python_exec_versions loop: "{{ python_executables.stdout_lines }}" changed_when: false ignore_errors: true # 忽略非Python解释器文件的报错 - name: 整理可执行文件的版本信息 ansible.builtin.set_fact: python_exec_versions_clean: >- {{ python_exec_versions.results | selectattr('rc', 'eq', 0) | map(attribute='stdout') | map('regex_replace', '^Python (\d+\.\d+\.\d+)$', '\1') | list }} - name: 合并包管理器与源码安装的版本并去重 ansible.builtin.set_fact: python_all_versions: "{{ (python_pkg_versions + python_exec_versions_clean) | unique }}"
内容的提问来源于stack exchange,提问作者user26423314
相关产品推荐
相关产品推荐

