如何在远程系统上使用Ansible模块移动/重命名文件/目录?我不想使用命令/shell任务,也不想将文件从本地系统复制到远程系统。
文件模块不复制远程系统上的文件。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
我发现命令模块中的创建选项很有用。这个怎么样:
- name: Move foo to bar command: creates="path/to/bar" mv /path/to/foo /path/to/bar
我曾经像Bruce P建议的那样使用统计数据进行2个任务方法。现在我用create完成一个任务。我觉得这清楚多了。
Bruce并没有试图统计目的地以检查是否移动已经在那里的文件;在尝试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
从2.0版开始,在复制模块中可以使用remote_src参数。
remote_src
如果True,它将转到src的远程/目标机器。
True
- 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
从2.8版开始 复制模块 remote_src支持递归复制。
这是我让它为我工作的方式:
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
上面的剧本,会检查是否文件abc。在将文件移动到TMP文件夹之前,XTS已经存在。
另一种实现方法是使用file和state: hard。
file
state: hard
这是我要做的一个例子:
- name: Link source file to another destination file: src: /path/to/source/file path: /target/path/of/file state: hard
虽然只在本地主机(OSX)上测试,但也应该在Linux上工作。我看不出是Windows。
注意,绝对路径是必需的。否则它不会让我创建链接。此外,您不能跨文件系统,因此使用任何已安装的媒体都可能失败。
硬链接非常类似于移动,如果你之后删除源文件:
- name: Remove old file file: path: /path/to/source/file state: absent
另一个好处是,当你在玩的时候,改变是持续的。因此,如果有人更改了源文件,任何更改都会反映在目标文件中。
你可以通过ls -l来验证文件的链接数。硬链接的数量显示在模式旁边(例如,当一个文件有2个链接时,rwxr-xr- x2)。
ls -l
这看起来有点过分,但是如果你想避免使用命令模块(我就是这样做的,因为它使用的命令不是幂等的),你可以结合使用copy和unarchive。
另一个对我来说很有效的选项是使用同步模块。然后使用file模块删除原始目录。
下面是文档中的一个例子:
- synchronize: src: /first/absolute/path dest: /second/absolute/path archive: yes delegate_to: "\{\{ inventory_hostname }}"
你可以通过
使用Ad Hoc命令
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
我知道这是一个年旧主题,但我感到沮丧,并为自己构建了一个角色,为任意文件列表做这件事。扩展到你认为合适的范围:
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
注意,此处硬链接比复制更可取,因为它固有地保留了所有权和权限(此外,不会为文件的第二个副本消耗更多的磁盘空间)。
Windows: —name:将旧文件夹移至备份目录 win_command: "cmd.exe /c move /Y \{\{sourcePath}} \{\{destinationFolderPath}}"
—name:将旧文件夹移至备份目录 win_command: "cmd.exe /c move /Y \{\{sourcePath}} \{\{destinationFolderPath}}"
要重命名,请使用重命名或任命令
- name: Move the src file to dest command: mv /path/to/src /path/to/dest args: removes: /path/to/src creates: /path/to/dest
它只在/path/to/src存在而/path/to/dest不存在时运行mv命令,因此它在每个主机上运行一次,移动文件,然后不再运行。
/path/to/src
/path/to/dest
mv
当我需要在几百台主机上移动一个文件或目录时,我会使用这种方法,其中许多主机可能在任何给定时间都处于关机状态。它是幂等的,可以安全地放在剧本里。
- name: Example hosts: localhost become: yes tasks: - name: checking if a file exists stat: path: "/projects/challenge/simplefile.txt" register: file_data - name: move the file if file exists copy: src: /projects/challenge/simplefile.txt dest: /home/user/test when: file_data.stat.exists - name: report a missing file debug: msg: "the file or directory doesn't exist" when: not file_data.stat.exists