如何使用远程系统上的Ansible任务移动/重命名文件

时间:2014-06-11 12:30:17

标签: ansible

如何使用远程系统上的Ansible模块移动/重命名文件/目录?我不想使用命令/ shell任务,我不想将文件从本地系统复制到远程系统。

12 个答案:

答案 0 :(得分:188)

从版本2.0 ,在copy module中,您可以使用remote_src参数。

如果True它将转到src的远程/目标机器。

- name: Copy files from foo to bar
  copy: remote_src=True src=/path/to/foo dest=/path/to/bar

如果要移动文件,则需要删除带文件模块的旧文件

- name: Remove old files foo
  file: path=/path/to/foo state=absent

答案 1 :(得分:178)

文件模块不会复制远程系统上的文件。 src参数仅在创建文件的符号链接时由文件模块使用。

如果要在远程系统上完全移动/重命名文件,那么最好的办法是使用命令模块调用相应的命令:

- name: Move foo to bar
  command: mv /path/to/foo /path/to/bar

如果你想获得幻想,那么你可以先使用stat模块来检查foo是否真的存在:

- name: stat foo
  stat: path=/path/to/foo
  register: foo_stat

- name: Move foo to bar
  command: mv /path/to/foo /path/to/bar
  when: foo_stat.stat.exists

答案 2 :(得分:97)

我发现命令模块中的creates选项很有用。怎么样:

- name: Move foo to bar
  command: creates="path/to/bar" mv /path/to/foo /path/to/bar

我曾经像Bruce P建议的那样使用stat进行2任务处理。现在,我将此作为创建的一项任务。我认为这更加清晰。

答案 3 :(得分:6)

另一个对我有用的选项是使用 synchronize module 。然后使用文件模块删除原始目录。

以下是文档中的示例:

- synchronize:
    src: /first/absolute/path
    dest: /second/absolute/path
    archive: yes
  delegate_to: "{{ inventory_hostname }}"

答案 4 :(得分:5)

实现此目标的另一种方法是将filestate: hard一起使用。

这是我开始工作的一个例子:

- name: Link source file to another destination
  file:
    src: /path/to/source/file
    path: /target/path/of/file
    state: hard

虽然只在localhost(OSX)上测试过,但也应该在Linux上运行。我无法告诉Windows。

请注意,需要绝对路径。否则它不会让我创建链接。此外,您无法跨文件系统,因此使用任何已安装的媒体可能会失败。

如果您之后删除源文件,则硬链接与移动非常相似:

- name: Remove old file
  file:
    path: /path/to/source/file
    state: absent

另一个好处是,当你处于游戏中时,变化会持续存在。因此,如果有人更改了源,则任何更改都会反映在目标文件中。

您可以通过ls -l验证文件的链接数量。模式旁边显示了硬链接的数量(例如,当文件有2个链接时,为rwxr-xr-x 2)。

答案 5 :(得分:4)

布鲁斯没有尝试统计目的地以检查是否移动文件(如果文件已经存在);在尝试使用mv之前,他确保要移动的文件确实存在。

如果您的兴趣(例如汤姆的话)仅在文件尚未存在的情况下才会移动,我认为我们仍然应该将布鲁斯的支票纳入其中:

- name: stat foo
  stat: path=/path/to/foo
  register: foo_stat

- name: Move foo to bar
  command: creates="path/to/bar" mv /path/to/foo /path/to/bar
  when: foo_stat.stat.exists

答案 6 :(得分:4)

- name: Move the src file to dest
  command: mv /path/to/src /path/to/dest
  args:
    removes: /path/to/src
    creates: /path/to/dest

这仅在 mv 存在而 /path/to/src 不存在时运行 /path/to/dest 命令,因此它在每个主机上运行一次,移动文件,然后不再运行。

当我需要在数百台主机上移动文件或目录时,我会使用这种方法,其中许多主机可能会在任何给定时间关闭。留在剧本中是幂等且安全的。

答案 7 :(得分:2)

我知道这是一个 YEARS 的老话题,但我为此感到沮丧,并为自己建立了一个角色,可以对任意文件列表执行此操作。视需要扩展:

main.yml

- name: created destination directory
  file:
    path: /path/to/directory
    state: directory
    mode: '0750'
- include_tasks: move.yml
  loop:
    - file1
    - file2
    - file3

move.yml

- name: stat the file
  stat:
    path: {{ item }}
  register: my_file

- name: hard link the file into directory
  file:
    src: /original/path/to/{{ item }}
    dest: /path/to/directory/{{ item }}
    state: hard
  when: my_file.stat.exists

- name: Delete the original file
  file:
    path: /original/path/to/{{ item }}
    state: absent
  when: my_file.stat.exists

请注意,硬链接胜于在此处复制,因为硬链接固有地保留了所有权和权限(除了不为文件的第二个副本占用更多的磁盘空间)。

答案 8 :(得分:1)

这是我让它为我工作的方式:

  Tasks:
  - name: checking if the file 1 exists
     stat:      
      path: /path/to/foo abc.xts
     register: stat_result

  - name: moving file 1
    command: mv /path/to/foo abc.xts /tmp
    when: stat_result.stat.exists == True

上面的剧本,在将文件移动到tmp文件夹之前,会检查文件是否存在abc.xts。

答案 9 :(得分:1)

在Windows上: - name: Move old folder to backup win_command: "cmd.exe /c move /Y {{ sourcePath }} {{ destinationFolderPath }}"

要重命名,请使用重命名 ren 命令

答案 10 :(得分:0)

这看起来有点矫枉过正,但是如果你想避免使用命令模块(我这样做,因为它使用命令不是幂等的)你可以使用复制和解压缩的组合。

  1. 使用tar存档您需要的文件。如果你提前考虑这实际上是有道理的。您可能需要给定目录中的一系列文件。使用所有文件创建该目录并将其存档在tar。
  2. 使用unarchive模块。当您这样做时,连同目标:和remote_src:关键字,您可以将所有文件复制到临时文件夹中,然后将它们打包到您想要的位置。

答案 11 :(得分:0)

您可以通过-

使用临时命令

ansible all -m command -a" mv /path/to/foo /path/to/bar"

或者如果您想使用剧本来做

- name: Move File foo to destination bar
  command: mv /path/to/foo /path/to/bar