条件的边界
条件用于跳过不适用的任务,语法看着简单,出错却集中在几处:字符串与布尔比较、多条件组合时的优先级、列表包含判断的方向、以及条件里引用了未定义的变量。可靠做法是让条件只回答一个布尔问题,复杂逻辑先拆成中间变量,必要时用断言把预期写清楚再执行。
基本信息
| 基本形式 | 单个布尔表达式、条件列表、包含测试、存在性测试 |
|---|---|
| 常用比较 | 相等与不等、数值比较、版本比较、集合包含 |
| 类型注意 | 布尔与字符串直接比较容易得到相反结果 |
| 调试方式 | 先用调试任务打印条件里涉及的变量与类型 |
典型使用场景
- 按发行版分支执行:判断系统族而不是硬编码主机名
- 按版本分支:用版本测试比较语义化版本,而不是字符串比大小
- 可选任务:变量已定义才执行,未定义时整段跳过
- 先探查再决策:读当前状态判断是否需要重启或重载
- 多条件组合:用显式表达式写清与或关系,必要时加括号
三种常见条件
三种常见条件
- name: 单条件 # 布尔表达式直写
ansible.builtin.debug:
msg: debian
when: ansible_os_family == 'Debian'
- name: 条件列表 # 列表内各项是与关系
ansible.builtin.debug:
msg: ready
when:
- ansible_os_family == 'Debian'
- nginx_port | int > 1024
- name: 版本判断 # 按语义化版本而不是字符串比较
ansible.builtin.debug:
msg: supported
when: ansible_distribution_version is version('20.04', '>=')写法与陷阱
| 写法 | 含义 | 陷阱 |
|---|---|---|
| 单个表达式 | 结果为布尔则执行 | 字符串非空即真,容易误判 |
| 条件列表 | 各项之间是关系 | 想做或关系必须显式书写 |
| 包含测试 | 元素是否属于集合 | 集合与元素位置写反 |
| 存在性测试 | 变量是否已定义 | 直接引用未定义变量会报错 |
条件列表里的各项是与关系。把两个条件并列写进列表却期望或,是最常见的逻辑错误,而且它不会报错,只会让任务在该跑的时候不跑。
用字符串比较布尔开关(例如判断是否等于 true)时,变量若被解析成布尔值,比较结果可能与预期相反。判断开关一律先转布尔再比较。
把条件写短
条件越长越难确认对错。经验做法是:把用到的判断拆成几个中间变量,在变量定义处写清含义,条件里只引用这些变量;分支超过三条时改用映射表或按分组区分主机,比在一行里堆叠比较运算符更好维护,也更容易被同事读懂。