115

我想推送到远程服务器的各个子目录中有大约 50 个左右的文件。我认为 rsync 可以使用 --include-from 选项为我执行此操作。没有 --exclude="*" 选项,目录中的所有文件都被同步,使用该选项,没有文件。

rsync -avP -e ssh --include-from=deploy/rsync_include.txt --exclude=* ./ root@0.0.0.0:/var/www/ --dry-run

我最初运行它是干的,0.0.0.0 显然被远程服务器的 IP 取代。rsync_include.txt 的内容是我要上传的文件的相对路径的新行分隔列表。

有没有更好的方法让我在星期一早上逃脱?

4

8 回答 8

276

有一个标志--files-from可以完全满足您的要求。来自man rsync

--files-from=FILE

使用此选项允许您指定要传输的文件的确切列表(从指定的 FILE 中读取或 - 用于标准输入)。它还调整了 rsync 的默认行为,使仅传输指定的文件和目录更容易:

  • --relative (-R) 选项是隐含的,它保留为文件中的每个项目指定的路径信息(如果要关闭它,请使用 --no-relative 或 --no-R)。

  • --dirs (-d) 选项是隐含的,它将创建在目标列表中指定的目录,而不是嘈杂地跳过它们(如果要关闭它,请使用 --no-dirs 或 --no-d )。

  • --archive (-a) 选项的行为并不意味着 --recursive (-r),因此如果需要,请明确指定它。

  • 这些副作用会改变 rsync 的默认状态,因此命令行中 --files-from 选项的位置与其他选项的解析方式无关(例如 -a 在 --files- 之前或之后的工作方式相同)来自,以及 --no-R 和所有其他选项)。

从 FILE 读取的文件名都是相对于源目录的——任何前导斜杠都被删除,并且不允许“..”引用高于源目录。例如,使用以下命令:

rsync -a --files-from=/tmp/foo /usr remote:/backup

如果 /tmp/foo 包含字符串“bin”(甚至是“/bin”),则 /usr/bin 目录将在远程主机上创建为 /backup/bin。如果它包含“bin/”(注意尾部斜杠),也会发送目录的直接内容(无需在文件中明确提及——这始于版本 2.6.4)。在这两种情况下,如果启用了 -r 选项,也会传输该目录的整个层次结构(请记住,需要使用 --files-from 显式指定 -r,因为 -a 没有暗示它)。另请注意,(默认启用)--relative 选项的效果是仅复制从文件中读取的路径信息——它不会强制复制源规范路径(在这种情况下为 /usr) .

此外,如果您在文件前面指定“host:”(主机必须匹配传输的一端),则可以从远程主机而不是本地主机读取 --files-from 文件。作为捷径,您可以只指定前缀“:”来表示“使用传输的远程端”。例如:

rsync -a --files-from=:/path/file-list src:/ /tmp/copy

这将复制位于远程“src”主机上的 /path/file-list 文件中指定的所有文件。

如果指定了 --iconv 和 --protect-args 选项并且 --files-from 文件名从一个主机发送到另一台主机,则文件名将从发送主机的字符集转换为接收主机的字符集。

注意:对 --files-from 输入中的文件列表进行排序有助于 rsync 更有效,因为它将避免重新访问在相邻条目之间共享的路径元素。如果输入没有排序,一些路径元素(隐含的目录)可能最终会被扫描多次,并且 rsync 最终会在它们变成文件列表元素后取消重复。

于 2015-05-11T20:05:35.783 回答
13

--files-from=如果要保持绝对路径不变,参数需要尾部斜杠。因此,您的命令将如下所示:

rsync -av --files-from=/path/to/file / /tmp/

这可以像有大量文件并且您想将所有文件复制到 x 路径一样完成。所以你会找到这些文件并将输出扔到一个文件中,如下所示:

find /var/* -name *.log > file
于 2016-01-22T11:01:55.473 回答
12

根据记录,除了一个之外,上述答案都没有帮助。总而言之,您可以--files-from=使用以下任一方式执行备份操作:

rsync -aSvuc `cat rsync-src-files` /mnt/d/rsync_test/

或者

rsync -aSvuc --recursive --files-from=rsync-src-files 。/mnt/d/rsync_test/

前一个命令是不言自明的,除了rsync-src-files我将在下面详细说明的文件内容之外。现在,如果你想使用后一个版本,你需要记住以下四点:

  1. 注意需要同时--files-from指定目录
  2. 需要明确指定--recursive
  3. 该文件rsync-src-files是用户创建的文件,它被放置在此测试的 src 目录中
  4. 包含要复制的rsyn-src-files文件和文件夹,它们相对于源目录。重要提示:确保文件中没有尾随空格或空行。在下面的示例中,只有两行,而不是三行(偶然发现)。内容rsynch-src-files为:

文件夹
名称 1 文件夹名称 2

于 2018-07-02T08:33:18.037 回答
3

编辑: atp 下面的答案更好。请使用那个!

如果您正在寻找特定的文件列表,您可能会更轻松,而是将它们直接放在命令行上:

# rsync -avP -e ssh `cat deploy/rsync_include.txt` root@0.0.0.0:/var/www/

然而,这是假设您的列表不会太长以至于命令行长度会成为问题,并且rsync_include.txt文件只包含真实路径(即没有注释,也没有正则表达式)。

于 2013-05-20T12:34:00.520 回答
3

我有类似的任务:rsync 在给定日期之后修改的所有文件,但不包括某些目录。很难构建一个一体式的班轮风格,所以我将问题分解成更小的部分。最终解决方案:

find  ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | egrep -v "/\..|Downloads|FOO" > FileList.txt
rsync -v --files-from=FileList.txt ~/sourceDIR /Destination

首先我使用find -L ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS". 我试图添加regexfind行以排除名称模式,但是我的 Linux (Mint) 风格无法理解find. 尝试了多种正则表达式 - 无法按需要工作。所以我最终得到egrep -v- 排除模式简单方法的选项。我rsync没有复制/.cache/.config 之类的目录以及我明确命名的其他目录。

于 2019-08-14T23:12:08.963 回答
2

该答案不是该问题的直接答案。但它应该可以帮助您找出最适合您的问题的解决方案。

分析问题时,您应该激活调试选项-vv

然后 rsync 将输出哪些文件被哪个模式包含或排除:

building file list ... 
[sender] hiding file FILE1 because of pattern FILE1*
[sender] showing file FILE2 because of pattern *
于 2019-02-10T10:00:50.340 回答
2

当我只有一个目录列表时,这些答案都不适合我。然后我偶然发现了解决方案!您必须添加-r--files-from因为-a在这种情况下不会递归(谁知道?!)。

rsync -aruRP --files-from=directory.list . ../new/location
于 2020-05-01T16:59:47.433 回答
2
$ date
  Wed 24 Apr 2019 09:54:53 AM PDT
$ rsync --version
  rsync  version 3.1.3  protocol version 31
  ...

句法:rsync <file_/_folder_list> <source> <target>

文件夹名称(这里,带有尾随/;例如Cancer - Evolution/)位于文件夹列表文件中(例如:cm_folder_list_test):

# /mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test
# test file: 2019-04-24
Cancer/
Cancer - Evolution/
Cancer - Genomic Variants/
Cancer - Metastasis (EMT Transition ...)/
Cancer Pathways, Networks/
Catabolism - Autophagy; Phagosomes; Mitophagy/
Catabolism - Lysosomes/

如果您不包括那些尾随/,则会创建 rsync 的目标文件夹,但它们是空的。

这些文件夹名称附加到其路径的其余部分 ( /home/victoria/Mail/2_RESEARCH - NEWS),从而为 rsync 提供完整的文件夹路径;例如:/home/victoria/Mail/2_RESEARCH - NEWS/Cancer - Evolution/

请注意,您还需要使用--files-from=...,而不是--include-from=...

rsync -aqP --delete --files-from=/mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test "/home/victoria/Mail/2_RESEARCH - NEWS" $IN/

(在我的 BASH 脚本中,我定义$IN了如下变量。)

BASEDIR="/mnt/Vancouver/projects/ie/claws"
IN=$BASEDIR/data/test/input

使用的 rsync 选项:

 -a  :   archive: equals -rlptgoD (no -H,-A,-X)
    -r  :   recursive
    -l  :   copy symlinks as symlinks
    -p  :   preserve permissions
    -t  :   preserve modification times 
    -g  :   preserve group 
    -o  :   preserve owner (super-user only) 
    -D  :   same as --devices --specials 
  -q  :   quiet (https://serverfault.com/questions/547106/run-totally-silent-rsync)

  --delete
    This  tells  rsync to delete extraneous files from the RECEIVING SIDE (ones
    that AREN’T ON THE SENDING SIDE), but only for the directories that are
    being synchronized.  You must have asked rsync to send the whole directory
    (e.g.  "dir" or "dir/") without using a wildcard for the directory’s contents
    (e.g. "dir/*") since the wildcard is expanded by the shell and rsync thus
    gets a request to transfer individual files, not the files’ parent directory.
    Files  that  are  excluded  from  the transfer are also excluded from being
    deleted unless you use the --delete-excluded option or mark the rules as
    only matching on the sending side (see the include/exclude modifiers in the
    FILTER RULES section).  ...
于 2019-04-24T17:03:53.400 回答