Ansible的when语句做条件判断

环境

  • 控制节点:Ubuntu 22.04
  • Ansible 2.10.8
  • 管理节点:CentOS 8

使用 when 语句做条件判断

创建文件 test1.yml 如下:

---
- hosts: alltasks:- name: task1debug:msg: "hello"when: 1 > 0- name: task2debug:msg: "OK"when: 1 > 2

运行结果如下:

......
TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {"msg": "hello"
}TASK [task2] ***************************************************************************************
skipping: [192.168.1.55]
......

可见,task满足条件,所以运行了;task2不满足条件,所以没有运行。

多个条件之间可以做逻辑运算(与或非),比如:

      when: ((1 > 0) and (1 < 2)) or (not (1 == 3))

多个 and 条件,也可以写成list的形式,比如:

      when:- 1 < 2- 2 < 3- 3 < 4

基于 ansible_facts 的条件判断

例如:

    - name: task3debug:msg: "hello"when: ansible_facts['os_family'] == "RedHat" #"Debian"

也可以先把ansible_facts先存为变量,再对变量做条件判断,比如:

    - name: task5block:- name: part1set_fact:version: "{{ ansible_facts['distribution_major_version'] }}"- name: part2debug:msg: "Horse"when: version | int >= 8

注:先用filter把变量转为int类型,再和整数8比较大小。

基于register变量的条件判断

这是一种常见的用法,上一个task把结果记录在变量里,下一个task根据该变量的值做条件判断。

---
- hosts: alltasks:- name: task1shell: cat /tmp/a.txt | wc -lregister: result- name: task2debug:msg: "More than 100 lines!"when: result.stdout | int > 1
  • 当文件超过100行时,结果如下:
......
TASK [task2] ***************************************************************************************
ok: [192.168.1.55] => {"msg": "More than 100 lines!"
}
......

当文件不超过100行时,结果如下:

......
TASK [task2] ***************************************************************************************
skipping: [192.168.1.55]
......

对register变量,可作如下判断:

  • is failed
  • is succeeded
  • is skipped
  • is changed

例如:

---
- hosts: alltasks:- name: task1ansible.builtin.command: /bin/falseregister: resultignore_errors: true- name: task2debug:msg: "Task fails!"when: result is failed- name: task3debug:msg: "Task succeeds!"when: result is succeeded- name: task4debug:msg: "Task skipped!"when: result is skipped- name: task5 debug:msg: "Task changed!"when: result is changed

基于变量的条件判断

注意: when 语句里的变量,不需要加 {{ }}

变量可转换成bool类型,例如:

---
- hosts: allvars:- var1: true- var2: false- var3: "yes"- var4: "no"tasks:- name: task1debug:msg: "task1"when: var1- name: task2debug:msg: "task2"when: not var2- name: task3debug:msg: "task3"when: var3 | bool- name: task4debug:msg: "task4"when: not (var4 | bool)

使用没有定义的变量会报错,所以,在使用变量前,可以先判断其是否定义:

  • is defined
  • is undifined

例如:

---
- hosts: alltasks:- name: task1debug:msg: "OK"when: var1 is defined and var1

这是一种非常常见的用法。

在循环里使用条件判断

loopwhen 可以一起用,对每次循环做条件判断。例如,遍历文件每一行,若内容超过2个字符,则打印其内容:

---
- hosts: alltasks:- name: task1shell: cat /tmp/a.txtregister: result- name: task2debug:msg: "{{ item }}"loop: "{{ result.stdout_lines }}"when: item | length > 2

假设 a.txt 内容如下:

aaaaa
b
ccccc

则运行结果如下:

TASK [task2] ***************************************************************************************
ok: [192.168.1.55] => (item=aaaaa) => {"msg": "aaaaa"
}
skipping: [192.168.1.55] => (item=b) 
ok: [192.168.1.55] => (item=ccccc) => {"msg": "ccccc"
}

也可以遍历/判断自定义的list或者dict,例如:

---
- hosts: allvars:- mylist1: [ 1, 2, 3 ]- mydict1: {"a": 10, "b": 20, "c": 30}tasks:- name: task1debug:msg: "{{ item }}"loop: "{{ mylist1 }}"when: item > 1- name: task2debug:msg: "{{ item }}"loop: "{{ query('dict', mydict1) }}"when: item.value > 10

运行结果如下:

......
TASK [task1] ***************************************************************************************
skipping: [192.168.1.55] => (item=1) 
ok: [192.168.1.55] => (item=2) => {"msg": 2
}
ok: [192.168.1.55] => (item=3) => {"msg": 3
}TASK [task2] ***************************************************************************************
skipping: [192.168.1.55] => (item={'key': 'a', 'value': 10}) 
ok: [192.168.1.55] => (item={'key': 'b', 'value': 20}) => {"msg": {"key": "b","value": 20}
}
ok: [192.168.1.55] => (item={'key': 'c', 'value': 30}) => {"msg": {"key": "c","value": 30}
}
......

注意,最好也判断一下变量是否定义,比如:

    - name: task3debug:msg: "{{ item }}"loop: "{{ mylist2 }}"when: mylist2 is defined and item > 1- name: task4debug:msg: "{{ item }}"loop: "{{ query('dict', mydict2) }}"when: mydict2 is defined and item.value > 10

或者提供一个缺省的空list/dict,例如:

    - name: task5debug:msg: "{{ item }}"loop: "{{ mylist2 | default([]) }}"when: item > 1- name: task6debug:msg: "{{ item }}"loop: "{{ query('dict', mydict2 | default({})) }}"when: item.value > 10

注意:task3和task4会skip,而task5和task6会运行。

import和include的条件判断

先看include。例如, main.yml 内容如下:

---
- hosts: alltasks:- name: task1include_tasks: test11.yml#import_tasks: test11.ymlwhen: var1 is not defined#vars:#  - var1: 111

test11.yml 内容如下:

---
- name: task1debug:msg: "var1 = {{ var1 }}"when: var1 is defined- name: task2debug:msg: "I am  task2"- name: task3set_fact:var1: 123when: var1 is not defined- name: task4debug:msg: "var1 = {{ var1 }}"when: var1 is defined- name: task5debug:msg: "I am task5"

main.yml 中没有定义 var1 ,则运行结果如下:

TASK [main_task1] **********************************************************************************
included: /root/temp/temp1113_2/test11.yml for 192.168.1.55TASK [task1] ***************************************************************************************
skipping: [192.168.1.55]TASK [task2] ***************************************************************************************
ok: [192.168.1.55] => {"msg": "I am  task2"
}TASK [task3] ***************************************************************************************
ok: [192.168.1.55]TASK [task4] ***************************************************************************************
ok: [192.168.1.55] => {"msg": "var1 = 123"
}TASK [task5] ***************************************************************************************
ok: [192.168.1.55] => {"msg": "I am task5"
}

main.yml 中定义了 var1 ,则运行结果如下:

TASK [main_task1] **********************************************************************************
skipping: [192.168.1.55]

include_tasks 的逻辑比较直观:

  • 如果 main.yml 没有定义 var1 ,则满足条件,运行 test11.yml
  • 如果 main.yml 定义了 var1 ,则不满足条件,不运行 test11.yml

现在,把 include_tasks 换成 import_taskstest11.yml 内容不变。

main.yml 中没有定义 var1 ,则运行结果如下:

TASK [task1] ***************************************************************************************
skipping: [192.168.1.55]TASK [task2] ***************************************************************************************
ok: [192.168.1.55] => {"msg": "I am  task2"
}TASK [task3] ***************************************************************************************
ok: [192.168.1.55]TASK [task4] ***************************************************************************************
skipping: [192.168.1.55]TASK [task5] ***************************************************************************************
skipping: [192.168.1.55]

main.yml 中定义了 var1 ,则运行结果如下:

TASK [task1] ***************************************************************************************
skipping: [192.168.1.55]TASK [task2] ***************************************************************************************
skipping: [192.168.1.55]TASK [task3] ***************************************************************************************
skipping: [192.168.1.55]TASK [task4] ***************************************************************************************
skipping: [192.168.1.55]TASK [task5] ***************************************************************************************
skipping: [192.168.1.55]

import_tasks 的运行结果和 include_tasks 大不相同。这是因为, import_tasks 是在预编译期,就把引用的task替换过来了(注意在运行结果里并没有出现 main_task1 的字眼),所以就相当于把 when 的条件判断放到 test11.yml 的每个task里了:

---
- name: task1debug:msg: "var1 = {{ var1 }}"when: var1 is defined and var1 is not defined- name: task2debug:msg: "I am  task2"when: var1 is not defined- name: task3set_fact:var1: 123when: var1 is not defined and var1 is not defined- name: task4debug:msg: "var1 = {{ var1 }}"when: var1 is defined and var1 is not defined- name: task5debug:msg: "I am task5"when: var1 is not defined

这样就能理解运行结果了。

注意: main_task1 里的变量定义,并没有放到 test11.yml 的每个task里。

创建文件 main.yml 如下:

---
- hosts: alltasks:- name: main_task1import_tasks: test13.ymlvars:- var1: 111

创建文件 test13.yml 如下:

---
- name: task1debug:msg: "var1 = {{ var1 }}"when: var1 is defined- name: task2set_fact:var1: 123- name: task3debug:msg: "var1 = {{ var1 }}"when: var1 is defined

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {"msg": "var1 = 111"
}TASK [task2] ***************************************************************************************
ok: [192.168.1.55]TASK [task3] ***************************************************************************************
ok: [192.168.1.55] => {"msg": "var1 = 123"
}

可见,task1和task3打印的 var1 变量值并不相同。前者是从 main.yml 而来,后者是从task2而来。

注:关于 import_xxxinclude_xxx ,参见我另一篇文档。

调试

最简单的方法就是打印出来看一下。比如:

---
- hosts: alltasks:- name: task1set_fact:var1: '123'- name: task2debug:msg: "var1 = {{ var1 }}"when: var1 == 123

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55]TASK [task2] ***************************************************************************************
skipping: [192.168.1.55]

可以看到,task2被skip了,这是因为 when 语句没有满足条件。

要确认的话,可以把条件判断的结果打印出来:

......- name: task3debug:var: var1 == 123
......

运行结果如下:

......
TASK [task3] ***************************************************************************************
ok: [192.168.1.55] => {"var1 == 123": false
}
......

可见条件判断的结果确实是false。

注意:用的是 debugvar 打印条件判断的结果。

接下来,可以打印出来变量看一下其值:

......- name: task4debug:var: var1
......

运行结果如下:

......
TASK [task4] ***************************************************************************************
ok: [192.168.1.55] => {"var1": "123"
}
......

可见 var1 的值是 "123" ,是一个字符串(如果是数值则是 123 )。

当然,更直接的办法是查看一下 var1 的类型:

......- name: task5debug:msg: "{{ var1 | type_debug }}"
......

运行结果如下:

......
TASK [task5] ***************************************************************************************
ok: [192.168.1.55] => {"msg": "AnsibleUnicode"
}
......

如果是数值,则类型是 int

因为 var1 是字符串,而 123 是整数,所以task2的判断条件不满足。

修改方法为:

原先为: var1 == 123
应改为: var1 == '123' ,或者 var1 | int == 123

参考

  • https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_conditionals.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/153958.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电力感知边缘计算网关产品设计方案-业务流程设计

1.工业数据通信流程 工业数据是由仪器仪表、PLC、DCS等工业生产加工设备提供的,通过以太网连接工业边缘计算网关实现实时数据采集。按照现有的通信组网方案,在理想通信状态下可以保证有效获取工业数据的真实性和有效性。 边缘计算数据通信框架图: 2.边缘计算数据处理方案 …

makefile备忘

结构描述 目标 … : 依赖 … 命令1 命令2 . . . 标记符 CFLAGS $^ 表示所有的依赖文件 $ 表示生成的目标文件 $< 代表第一个依赖文件 调试信息选项&#xff1a;-g优化选项&#xff1a;-O编译警告选项&#xff1a;-Wall指定包含目录选项&#xff1a;-I指定库目录选项&am…

Linux驱动开发——块设备驱动

目录 一、 学习目标 二、 磁盘结构 三、块设备内核组件 四、块设备驱动核心数据结构和函数 五、块设备驱动实例 六、 习题 一、 学习目标 块设备驱动是 Linux 的第二大类驱动&#xff0c;和前面的字符设备驱动有较大的差异。要想充分理解块设备驱动&#xff0c;需要对系统…

高效开发与设计:提效Spring应用的运行效率和生产力 | 京东云技术团队

引言 现状和背景 Spring框架是广泛使用的Java开发框架之一&#xff0c;它提供了强大的功能和灵活性&#xff0c;但在大型应用中&#xff0c;由于Spring框架的复杂性和依赖关系&#xff0c;应用的启动时间和性能可能会受到影响。这可能导致开发过程中的迟缓和开发效率低下。优…

Golang基础-面向过程篇

文章目录 基本语法变量常量函数import导包匿名导包 指针defer静态数组动态数组(slice)定义方式slice追加元素slice截取 map定义方式map使用方式 基本语法 go语言输出hello world的语法如下 package mainimport ("fmt""time" )func main() {fmt.Println(&…

以太网基础——DoIP报文类型

文章目录 前言一、DoIP payload types二、节点管理报文0x0000:Generic DoIP header negative acknowledge0x0001:Vehicle identification request message0x0002:Vehicle identification request message with EID0x0003:Vehicle identification request message with VIN0…

循环链表2

循环链表的实现 对于数据结构中所有的结构而言&#xff0c;每一次都是用之前初始化&#xff08;处理一开始的随机值&#xff09;一下&#xff0c; 用完销毁&#xff08;不管有没有malloc都能用&#xff0c;用了可以保证没有动态内存泄漏了&#xff09;一下 而在C里面&#x…

Dubbo开发系列

一、概述 以上是 Dubbo 的工作原理图&#xff0c;从抽象架构上分为两层&#xff1a;服务治理抽象控制面 和 Dubbo 数据面 。 服务治理控制面。服务治理控制面不是特指如注册中心类的单个具体组件&#xff0c;而是对 Dubbo 治理体系的抽象表达。控制面包含协调服务发现的注册中…

PLC设备相关常用英文单词(一)

PLC设备相关常用英文单词&#xff08;一&#xff09; Baud rate 波特率Bus 总线Binary 二进制Configuration 组态Consistent data 一致性数据Counter 计数器Cycle time 循环时间Conveyor 传送Device names 设备名称Debug 调试Download 下载Expand 扩展Fix 固定Flow 流量Functio…

Netty 使用数字证书建立tsl(ssl),检查crl(证书吊销列表)

使用SslContext 建立ssl连接 File certChainFile new File("D:\\test\\test\\sdk_test03\\test_03.crt");File keyFile new File("D:\\test\\test\\sdk_test03\\test_03.key");File rootFile new File("D:/test/MyPKISubCAG1.crt");String c…

【LeetCode:689. 三个无重叠子数组的最大和 | 序列dp+前缀和】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

WMS系统先验后收策略

在制造业工厂的仓库管理中&#xff0c;确保物料的质量和数量是至关重要的。传统的仓库管理方式往往采用“先收后验”策略&#xff0c;即先接收物料&#xff0c;然后再进行质量检验。然而&#xff0c;这种方式存在一定的风险&#xff0c;例如不良品流入、数量不准确等问题。为了…

腾讯云服务器标准型S5实例CPU性能如何?配置特性说明

腾讯云服务器CVM标准型S5实例具有稳定的计算性能&#xff0c;CVM 2核2G S5活动优惠价格280.8元一年自带1M带宽&#xff0c;15个月313.2元、2核4G配置748.2元15个月&#xff0c;CPU内存配置还可以选择4核8G、8核16G等配置&#xff0c;公网带宽可选1M、3M、5M或10M&#xff0c;腾…

优思学院|现代质量管理实践与六西格玛方法论如何融合?

企业要解决质量问题必然需要涉及管理&#xff0c;然而&#xff0c;如果仅仅将六西格玛法视为一种质量管理方法&#xff0c;必定会导致六西格玛管理法的失败。六西格玛法是一种具有特定战略性的管理方法&#xff0c;它涉及到市场、顾客、产品、服务、流程、质量、价值链以及财务…

Pytorch完整的模型训练套路

Pytorch完整的模型训练套路 文章目录 Pytorch完整的模型训练套路以CIFAR10为例实践 数据集加载步骤 使用适当的库加载数据集&#xff0c;例如torchvision、TensorFlow的tf.data等。 将数据集分为训练集和测试集&#xff0c;并进行必要的预处理&#xff0c;如归一化、数据增强等…

深搜回溯剪枝-全排列

LCR 083. 全排列 - 力扣&#xff08;LeetCode&#xff09; 根据题意&#xff0c;要根据给定的整数数组&#xff0c;穷举出所有可能的排列&#xff0c;从直观的角度上来看&#xff0c;可以使用多层 for 循环来解决&#xff0c;但如果是数组长度太大的时候&#xff0c;这种方式不…

配置Java环境变量不生效的解决办法

问题&#xff1a; 直接更换Java_HOME的JDK安装路径后&#xff0c;竟然环境变量不生效&#xff0c;在cmd窗口输入java -version或者javac -version后报错&#xff1f;&#xff1f;&#xff1f;这是为什么呢&#xff1f; 问题剖析&#xff1a; 在使用安装版本的JDK程序时&#…

DataFunSummit:2023年数据基础架构峰会-核心PPT资料下载

一、峰会简介 正如From、Join、排序等是SQL的基本算子&#xff0c;存储与计算是也是数据架构中数据生产与消费的基本算子&#xff0c;对于数据架构之下的技术栈层级&#xff0c;我们可将其定义为数据基础架构。 数据存储技术在适应大数据时代的规模需求基础之上&#xff0c;持…

30+的女生学习做软件测试有前景吗?

首先&#xff0c;软件测试是一个非常重要的领域。无论是在互联网、金融、医疗、物流等行业&#xff0c;软件测试都是确保软件质量的重要环节。 软件测试通过对软件的功能、性能、稳定性等方面进行测试&#xff0c;保证软件能够正常运行并满足用户需求。随着信息技术的迅速发展…

【23真题】难!985难度前五名!

今天分享的是23年中山大学884的信号与系统试题及解析。 本套试卷难度分析&#xff1a;22年中山大学884考研真题&#xff0c;我也发布过&#xff0c;若有需要&#xff0c;戳这里自取!22年并不是很难&#xff0c;今年难度突然大幅度提升&#xff01;原因不明。23年平均分为100分…