使用Ansible复制多个文件


104

我如何在任务中通过Ansible将多个文件复制到远程节点中?

我尝试在任务中复制复制模块行以定义文件,但它仅复制第一个文件。

Answers:


131

您可以with_fileglob为此使用循环:

- copy:
    src: "{{ item }}"
    dest: /etc/fooapp/
    owner: root
    mode: 600
  with_fileglob:
    - /playbooks/files/fooapp/*

3
如果将所有文件都放在同一根目录中以复制到远程计算机中,那么该方法可能会对我有帮助,那么在各个目录中包含一些文件又如何呢?例如,我想从3个不同的目录中复制3个文件
Mark

嗨,我正在尝试移动我所有的文件,/roles/db/files但无法通过这种方法使用它。我已经尝试过了,with_fileglob: - /roles/db/file/* 但是不会走好路
Batman

这种方法的最大缺点是它会使目录结构变平整。
昆丁

115
- name: Your copy task
  copy: src={{ item.src }} dest={{ item.dest }}
  with_items:
    - { src: 'containerizers', dest: '/etc/mesos/containerizers' }
    - { src: 'another_file', dest: '/etc/somewhere' }
    - { src: 'dynamic', dest: '{{ var_path }}' }
  # more files here

是否有可能将此解决方案的dest集合作为变量?{ src: 'containerizers', dest: {{ containerizers }} }
Gesias '17

2
@Gesias,是的。实际上,双方都可以是变量:{ src: '{{ source.var }}', dest: '{{ dest.var }}' }
ntwrkguru

16

您可以将with_together用于此目的:

- name: Copy multiple files to multiple directories
  copy: src={{ item.0 }} dest={{ item.1 }}
  with_together:
    - [ 'file1', 'file2', 'file3' ]
    - [ '/dir1/', '/dir2/', '/dir3/' ]

虽然有效,但这在语义上并不干净-有更干净的选项。
plesiv

11

如果需要多个位置,则需要多个任务。一个复制任务只能从一个位置(包括多个文件)复制到节点上的另一个位置。

- copy: src=/file1 dest=/destination/file1
- copy: src=/file2 dest=/destination/file2

# copy each file over that matches the given pattern
- copy: src={{ item }} dest=/destination/
  with_fileglob:
    - /files/*

-名称:复制file1复制:src = / file1 dest = /目标/ file1-名称:复制file2复制:src = / file2 dest = / destination / file2
标记

要看。更简单,也可能更简洁,但是可以使用更复杂的数据结构来完成,例如带有with_items的带有源和目标数据的匿名词典列表。每种语言都一样-您必须做出判断。在某些情况下,委派功能比一连串的复制/粘贴if语句更为有效和可维护。我真是个怪胎,宁愿保持结构良好的代码简洁,也不愿花大量冗长而乏味的近乎相同的指令,但是我不认为所有人都同意。做对您来说可维护的事情。
Paul Hodges '18

8

从Ansible 2.5开始,不建议使用with_*构造,而应使用语法。一个简单的实际示例:loop

- name: Copy CA files
  copy:
    src: '{{item}}'
    dest: '/etc/pki/ca-trust/source/anchors'
    owner: root
    group: root
    mode: 0644
  loop:
    - symantec-private.crt
    - verisignclass3g2.crt


7
- hosts: lnx
  tasks:
    - find: paths="/appl/scripts/inq" recurse=yes patterns="inq.Linux*"
      register: file_to_copy
    - copy: src={{ item.path }} dest=/usr/local/sbin/
      owner: root
      mode: 0775
      with_items: "{{ files_to_copy.files }}"

只是一个侧面说明,该find模块仅适用于ansible 2.x,而不适用于ansible 1.x
Arbab Nazar 16'Aug9

我已经修正了您的答案,因为您stdout_lines在返回值中提到了,但不适用于find模块。它只有filesexaminedmatched作为返回值。希望对别人有帮助
Arbab Nazar

2
有人能够将文件复制到远程节点吗?find似乎只看远程系统,不允许从管理节点获取任何内容。这些答案,使用with_fileglob,似乎更加恰当:stackoverflow.com/a/42290160/272387stackoverflow.com/a/36720342/272387
Richlv '17

4

或者您可以使用with_items:

- copy:
    src: "{{ item }}"
    dest: /etc/fooapp/
    owner: root
    mode: 600
  with_items:
    - dest_dir

3
- name: find inq.Linux*
  find:  paths="/appl/scripts/inq" recurse=yes patterns="inq.Linux*"
  register: find_files


- name: set fact
  set_fact:
    all_files:
      - "{{ find_files.files | map(attribute='path') | list }}"
  when: find_files > 0


- name: copy files
  copy:
    src: "{{ item }}"
    dest: /destination/
  with_items: "{{ all_files }}"
  when: find_files > 0

6
一个好的答案不仅包含代码,还包含一些解释或文档参考。
劳伦兹·阿尔贝

Ansible文档中对find,set_fact和copy模块进行了说明。如果您想进一步了解此部分,请阅读有关过滤器的信息,并在ansible文档中进行了说明(-“ {{find_files.files | map(attribute'path')| list}}”)
Fredric Andersson

1

您可以使用目录列表遍历变量:

- name: Copy files from several directories
  copy:
    src: "{{ item }}"
    dest: "/etc/fooapp/"
    owner: root
    mode: "0600"
  loop: "{{ files }}"
  vars:
    files:
      - "dir1/"
      - "dir2/"

1

使用以下源代码在客户端计算机上复制多个文件。


 - name: Copy data to the client machine
   hosts: hostname
   become_method: sudo
   become_user: root
   become: true
   tasks: 
     # Copy twice as sometimes files get skipped (mostly only one file skipped from a folder if the folder does not exist)
     - name: Copy UFO-Server 
       copy:
         src: "source files path"
         dest: "destination file path"
         owner: root
         group: root
         mode: 0644
         backup: yes
       ignore_errors: true

注意:

如果要通过使用变量传递多个路径,则

src:“ / root / {{item}}”

如果通过对不同项目使用变量来传递路径,则

src:“ / root / {{item.source_path}}”


0

copymodule是复制许多文件和/或目录结构的错误工具,请改用synchronizemodule rsync作为后端。注意,它需要同时rsync安装在控制器和目标主机上。它非常强大,请查看Ansible文档

示例-将文件从build控制器的目录(带有子目录)复制到/var/www/html目标主机上的目录:

synchronize:
  src: ./my-static-web-page/build/
  dest: /var/www/html
  rsync_opts:
    - "--chmod=D2755,F644" # copy from windows - force permissions
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.