Ansible技术问题:如何检查列表值是否存在于已注册变量中?
检查Oracle数据库指定补丁是否已安装
需求说明
需验证列表db_home_desired_patches_list中的所有补丁编号,是否已存在于Oracle数据库主目录的已安装补丁列表中(通过opatch lspatches命令获取)。
原Ansible任务代码
- name: 获取dbhome_1的已安装补丁列表 shell: | $ORACLE_HOME/OPatch/opatch lspatches environment: ORACLE_HOME: "{{ db_home_1 }}" PATH: $ORACLE_HOME/bin:$ORACLE_HOME/lib:$PATH:/usr/bin register: lspatches failed_when: ' db_home_desired_patches_list | difference (lspatches.stdout_lines) | length > 0 '
期望补丁列表示例
[ "35985645", "35778398", "35597425", "34939189" ]
opatch lspatches命令输出示例
35985645;EVEV-DEV2 DB CONTINUOUS RESTARTS WITH ORA-00600 INTERNAL ERROR CODE, ARGUMENTS [KDIFIND KCBZ_OBJDCHK] 35778398;FURTHER FIXES FOR ROW CACHE ON TOP OF 34304965 35098441;LOGMINER FAILS TO PURGE LOGMNRC_TSPART AND OTHER SHARD TABLES 35597425;ORA-600 723 IN RFS PROCESS 34939189;TRAIL FILE CORRUPTION DBFS 36130656;MERGE ON DATABASE RU 19.22.0.0.0 OF 36092993 35511348;AIM ORA-7445 [KNLCAPINSPROC] - KNLCAPINSPROC 36130831;MERGE ON DATABASE RU 19.22.0.0.0 OF 35989319
问题分析与修正方案
原任务逻辑存在问题:lspatches.stdout_lines中的每一行包含补丁编号和描述信息(格式为补丁号;描述),而db_home_desired_patches_list仅存储纯补丁编号,直接使用difference过滤器会导致所有期望补丁被判定为未安装。
需要先从lspatches.stdout_lines中提取纯补丁编号,再与期望列表对比。修正后的任务代码如下:
- name: 获取dbhome_1的已安装补丁列表 shell: | $ORACLE_HOME/OPatch/opatch lspatches environment: ORACLE_HOME: "{{ db_home_1 }}" PATH: $ORACLE_HOME/bin:$ORACLE_HOME/lib:$PATH:/usr/bin register: lspatches - name: 检查所有期望补丁是否已安装 fail: msg: "以下补丁未安装: {{ missing_patches | join(', ') }}" when: missing_patches | length > 0 vars: # 从已安装补丁输出中提取纯编号 installed_patches: "{{ lspatches.stdout_lines | map('split', ';') | map('first') | list }}" # 计算未安装的补丁 missing_patches: "{{ db_home_desired_patches_list | difference(installed_patches) }}"
逻辑说明
- 使用
split(';')将每一行按分号拆分,取拆分后的第一个元素(即补丁编号),得到已安装补丁的纯编号列表installed_patches。 - 通过
difference过滤器对比期望列表和已安装列表,得到未安装的补丁列表missing_patches。 - 如果存在未安装补丁,触发失败并输出具体补丁编号。
内容的提问来源于stack exchange,提问作者vijaymec50
相关产品推荐
相关产品推荐

