You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible多主机条件判断异常:标准Cron任务未按预期排除指定主机

问题:Ansible多主机排除条件下Cron任务判断失效

我正尝试配置两种不同的cron任务:部分主机需执行标准cron任务,其余主机执行故障转移cron任务,同时要将somescript.sh复制到所有主机。

主机清单片段

[zaspare]
host01.example.com
host02.example.com
host03.example.com
host04.example.com
host05.example.com
host06.example.com
host07.example.com
host08.example.com

原Playbook(存在问题)

---

- name: Updating somescript
  hosts: zaspare
  become: yes

  tasks:


  - name: Copy somescript.sh script to /usr/local/bin
    copy:
      src: somescript.sh
      dest: /usr/local/bin/
      owner: root
      group: root
      mode: 0755
      
  - name: Setup standard crontab for somescript    
    cron:
      name: Run somescript.sh
      job: /usr/local/bin/somescript.sh {{ inventory_hostname }} false 
      cron_file: somescript
      user: root
      minute: "10"
      hour: "22"
    when: inventory_hostname != "host01.example.com" or 
          inventory_hostname != "host02.example.com" or
          inventory_hostname != "host03.example.com" or
          inventory_hostname != "host04.example.com" or
          inventory_hostname != "host05.example.com"       

  - name: Setup failover crontab for somescript    
    cron:
      name: Run somescript.sh
      job: /usr/local/bin/somescript.sh {{ inventory_hostname }} true 
      cron_file: somescript
      user: root
      minute: "10"
      hour: "22"
    when: inventory_hostname == "host01.example.com" or 
          inventory_hostname == "host02.example.com" or
          inventory_hostname == "host03.example.com" or
          inventory_hostname == "host04.example.com" or
          inventory_hostname == "host05.example.com"

执行结果异常

TASK [Setup standard crontab for somescript]******************************
changed: [host06.example.com]
changed: [host07.example.com]
changed: [host01.example.com]
changed: [host08.example.com]
changed: [host02.example.com]
changed: [host04.example.com]
changed: [host03.example.com]
changed: [host05.example.com]

TASK [Setup failover crontab for somescript]******************************
skipping: [host06.example.com]
skipping: [host07.example.com]
skipping: [host08.example.com]
changed: [host01.example.com]
changed: [host02.example.com]
changed: [host03.example.com]
changed: [host04.example.com]
changed: [host05.example.com]

单主机排除时Playbook可正常工作,但多主机排除时标准Cron任务在所有主机上都执行了。


解答

问题出在逻辑运算符使用错误:

你在标准Cron任务的when条件里用了or,但实际需要的是and。举个例子,对于host01.example.com,inventory_hostname != "host02.example.com"这个条件是成立的,所以整个or组合的结果为真,导致任务执行。

正确的逻辑应该是:仅当主机名不是host01到host05中的任何一个时,才执行标准Cron任务,也就是所有的!=条件必须同时满足,所以要用and连接。

另外,更简洁且易维护的写法是把需要排除的主机放到一个列表里,用not in来判断:

修正后的Playbook

---

- name: Updating somescript
  hosts: zaspare
  become: yes

  vars:
    failover_hosts:
      - host01.example.com
      - host02.example.com
      - host03.example.com
      - host04.example.com
      - host05.example.com

  tasks:

  - name: Copy somescript.sh script to /usr/local/bin
    copy:
      src: somescript.sh
      dest: /usr/local/bin/
      owner: root
      group: root
      mode: 0755
      
  - name: Setup standard crontab for somescript    
    cron:
      name: Run somescript.sh
      job: /usr/local/bin/somescript.sh {{ inventory_hostname }} false 
      cron_file: somescript
      user: root
      minute: "10"
      hour: "22"
    when: inventory_hostname not in failover_hosts       

  - name: Setup failover crontab for somescript    
    cron:
      name: Run somescript.sh
      job: /usr/local/bin/somescript.sh {{ inventory_hostname }} true 
      cron_file: somescript
      user: root
      minute: "10"
      hour: "22"
    when: inventory_hostname in failover_hosts

这种写法不仅逻辑清晰,后续要添加或移除故障转移主机时,只需要修改failover_hosts变量即可,不需要调整条件判断语句。


内容的提问来源于stack exchange,提问作者Bianca_K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 05:20:48