使用 Ansible 在远程系统上移动文件,仅当目标不存在时

Move files on remote system, only if destination doesn't exist, with Ansible

我正在尝试编写一个 Ansible 角色来移动远程系统上的多个文件。我找到了一个关于如何做到这一点的 Stack Overflow post,它基本上说 "just use the command module with 'mv'"。我有一个用 with_items 语句定义的单个任务,其中 dirs 中的每个项目都是带有 srcdest 键的字典:

- name: Move directories
  command: mv {{ item.src }} {{ item.dest }}
  with_items: dirs

这很好而且有效,但是如果目标目录已经存在,我 运行 就会遇到问题。我不想覆盖它,所以我想先尝试统计每个 dest 目录。我想用统计信息更新 dirs 变量,但据我所知,一旦定义变量,就没有设置或更新变量的好方法。所以我使用 stat 获取每个目录的信息,然后使用 register:

保存数据
- name: Check if directories already exist
  stat: path={{ item.dest }}
  with_items: dirs
  register: dirs_stat

有没有办法将注册的统计信息绑定到 mv 命令?如果它是单个目录,这将很容易。循环使这变得棘手。有没有办法在不将此循环展开为每个目录两个任务的情况下执行此操作?

无论如何这都不是最简单的解决方案,但是如果您想使用 Ansible 而不是 "unroll":

---
- hosts: all
  vars:
    dirs:
      - src: /home/ubuntu/src/test/src1
        dest: /home/ubuntu/src/test/dest1
      - src: /home/ubuntu/src/test/src2
        dest: /home/ubuntu/src/test/dest2
  tasks:
    - stat:
        path: "{{item.dest}}"
      with_items: dirs
      register: dirs_stat
    - debug:
        msg: "should not copy {{ item.0.src }}"
      with_together:
        - dirs
        - dirs_stat.results
      when: item.1.stat.exists

只需将调试任务调整为 运行 适当的 command 任务,将 when: 调整为 when: not ...

您可以在 playbook 中使用 stat 关键字来检查它是否存在,如果它不存在则移动。

---
- name: Demo Playbook
  hosts: all
  become: yes
  tasks:
  - name: check destination
    stat:
     path: /path/to/dest
    register: p
  - name:  copy file if not exists
    command: mv /path/to/src /path/to/src
    when: p.stat.exists == False