【发布时间】:2016-08-10 08:47:43
【问题描述】:
如何在任务中通过 Ansible 将多个文件复制到远程节点?
我试图在我的任务中复制复制模块行来定义文件,但它只复制第一个文件。
【问题讨论】:
标签: ansible
如何在任务中通过 Ansible 将多个文件复制到远程节点?
我试图在我的任务中复制复制模块行来定义文件,但它只复制第一个文件。
【问题讨论】:
标签: ansible
您可以为此使用with_fileglob 循环:
- copy:
src: "{{ item }}"
dest: /etc/fooapp/
owner: root
mode: 600
with_fileglob:
- /playbooks/files/fooapp/*
【讨论】:
/roles/db/files 中移动所有文件,但我无法使用这种方法。我试过with_fileglob: - /roles/db/file/*,但路径不好
- 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 }} }.
{ src: '{{ source.var }}', dest: '{{ dest.var }}' }
从 Ansible 2.5 开始,应该使用 with_* 构造 are not recommended 和 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
【讨论】:
with_* 不已被弃用:“我们尚未弃用with_<lookup> - 该语法仍然适用于可预见的未来。” (截至 2021 年 11 月)他们只推荐它。
你可以使用 with_together 来达到这个目的:
- name: Copy multiple files to multiple directories
copy: src={{ item.0 }} dest={{ item.1 }}
with_together:
- [ 'file1', 'file2', 'file3' ]
- [ '/dir1/', '/dir2/', '/dir3/' ]
【讨论】:
如果您需要多个位置,则需要多个任务。一个复制任务只能从一个位置(包括多个文件)复制到节点上的另一个位置。
- 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/*
【讨论】:
- 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
stdout_lines,但不适用于find 模块。它只有files、examined 和matched 作为返回值。希望对其他人有所帮助
find 似乎只查看远程系统,不允许从管理节点获取任何东西。这些答案,使用with_fileglob,似乎更合适:stackoverflow.com/a/42290160/272387,stackoverflow.com/a/36720342/272387。
- 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
【讨论】:
或者你可以使用 with_items:
- copy:
src: "{{ item }}"
dest: /etc/fooapp/
owner: root
mode: 600
with_items:
- dest_dir
【讨论】:
copy 模块是复制许多文件和/或目录结构的错误工具,请使用synchronize 模块,而不是使用rsync 作为后端。请注意,它需要在控制器和目标主机上安装rsync。真的很强大,查看ansible documentation。
示例 - 将文件从控制器的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
【讨论】:
您可以使用目录列表遍历变量:
- name: Copy files from several directories
copy:
src: "{{ item }}"
dest: "/etc/fooapp/"
owner: root
mode: "0600"
loop: "{{ files }}"
vars:
files:
- "dir1/"
- "dir2/"
【讨论】:
使用以下源代码在您的客户端计算机上复制多个文件。
- 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 }}"
【讨论】:
这里是复制文件的通用解决方案:
...
- name: Find files you want to move
ansible.builtin.find:
paths: /path/to/files/
file_type: file
excludes: "*.txt" # Whatever pattern you want to exclude
register: files_output
- name: Copy the files
ansible.builtin.copy:
src: "{{ item.path }}"
dest: /destination/directory/
loop: "{{ files_output.files }}"
...
这比使用with_fileglob 更强大,因为您可以使用正则表达式进行匹配。下面是这个游戏的实际效果:
$ ls /path/to/files
demo.yaml test.sh ignore.txt
$ ls /destination/directory
file.h
$ ansible-playbook playbook.yaml
...[some output]...
$ ls /destination/directory
file.h demo.yaml test.sh
从上面的例子可以看出,ignore.txt 没有被复制到目标目录,因为 playbook 中的 excludes 正则表达式。仅使用with_fileglob 无法忽略此类文件。
此外,您可以相对轻松地从多个目录移动文件:
...
- name: Find files you want to move
ansible.builtin.find:
paths: /path/to/files/
# ... the rest of the task
register: list1
- name: Find more files you want to move
ansible.builtin.find:
paths: /different/path/
# ... the rest of the task
register: list2
- name: Copy the files
ansible.builtin.copy:
src: "{{ item.path }}"
dest: /destination/directory/
loop: "{{ list1.files + list2.files }}"
...
【讨论】:
这是一个示例 Ansible 脚本,用于在远程主机上复制多个文件
ansible.windows.win_copy:
src: "{{ SrcPath }}/{{ item}}" #Remeber to use {{item}} as a postfix to source path
dest: "{{destPath}}"
remote_src: yes [if Source Path available on remote Host]
with_items:
- abc.txt
- abc.properties
【讨论】:
【讨论】:
使用 Ansible 将文件从多个目录复制到多个目录
我发现guenhter 的答案很有帮助,但还需要更改远程文件的模式。我没有足够的声誉将此作为评论,这将是一个更合适的地方。在示例中,我将两个目录中的两个文件复制到 /tmp 和 /tmp/bin 中,我首先创建并修改远程文件模式。
- name: cpldupd
hosts: test
remote_user: root
become: true
vars:
- rpth: /tmp
tasks:
- name: Create '{{rpth}}/bin'
file:
path: '{{rpth}}/bin'
state: directory
- name: Transfer
copy: src={{ item.src }} dest={{ item.dest }} mode=0775
with_items:
- { src: '../utils/cpldupd', dest: '{{rpth}}/cpldupd' }
- { src: '../utils/bin/cpldupd', dest: '{{rpth}}/bin/cpldupd' }
【讨论】:
mode 已经出现在其他几个答案中,所以不需要再说一遍。