Ansible when子句AND条件内嵌OR逻辑不生效报错问题咨询
根因分析
- 第一个诱因是grep命令的返回码逻辑:当grep未匹配到目标字符串时,默认返回码为1,Ansible的shell模块会将返回码非0的任务判定为执行失败,此时注册的结果变量不会生成
stdout属性,直接调用变量.stdout就会触发'dict object' has no attribute 'stdout'报错。 - 第二个诱因是Ansible条件判断的短路求值规则:OR逻辑从左到右依次计算,左侧条件成立时不会校验右侧逻辑;左侧逻辑计算出错时会直接抛出异常,不会继续执行右侧校验。这也完全匹配观察到的现象:
- 当
rename_syn_result_chk_b匹配到successfully时,左侧条件成立,不会调用右侧rename_syn_result_chk_a的属性,任务正常执行 - 当
rename_syn_result_chk_b未匹配到successfully时,首先调用rename_syn_result_chk_b.stdout就会触发属性不存在的错误,根本不会校验右侧rename_syn_result_chk_a是否匹配,直接报错。
- 当
修复步骤
- 首先修改两个grep检查任务的配置,强制任务无论是否匹配到内容都判定为成功,保证注册变量始终存在
stdout属性:
- name: "check rename to synonym A" shell: | grep '{{ item.synA_name }}' `ls {{sql_log_dir}}/Rename_Hist2Syn*|tail -1` register: rename_syn_result_chk_a failed_when: false # 新增配置,无论grep返回码多少都不判定任务失败 - name: "check rename to synonym B" shell: | grep '{{ item.synB_name }}' `ls {{sql_log_dir}}/Rename_Hist2Syn*|tail -1` register: rename_syn_result_chk_b failed_when: false # 新增配置
- 优化when子句的写法,用Ansible原生的字符串包含判断替代find方法,同时添加默认值兜底,避免极端场景下的属性缺失报错:
- name: "invoke playbook for control tables update" include_tasks: sdp_purge_control_tbl.yml when: - job_exec_state.stdout.find('OK') == -1 - data_in_main_a.stdout.find('created')!= -1 - "'successfully' in (rename_syn_result_chk_b.stdout | default('')) or 'successfully' in (rename_syn_result_chk_a.stdout | default(''))" ignore_errors: True
内容的提问来源于stack exchange,提问作者gabriela gonzález
相关产品推荐
相关产品推荐

