rsync

来自百合仙子's Wiki
跳转到导航 跳转到搜索

文件同步工具。

示例

rsync -aviAX --delete SRC TARGET

同步匹配指定模式的文件,同时更改权限

rsync -avi --delete --chmod=u=rwX,go=rX --inplace phone:/sdcard/DCIM/100ANDRO/ '--include=DSC_03*' '--exclude=*' .

一个实用的别名:

alias xcp="rsync -aviHAXKhP --delete --exclude='*~' --exclude=__pycache__"

仅同步不同大小的、符合特定名字的文件(比如新添加的文件):

rsync -ri --size-only --info=progress2 --open-noatime --include='fsid_65f55515-*' --exclude='*' host:dir/ . -n

Windows 相关

在 FAT/NTFS 上,不保留权限,跟踪软链接:

rsync -virtOL --delete SRC TARGET

samba 上:

rsync --modify-window=5 -virtOL --delete SRC TARGET

-t-O保证正确的时间(设置文件时间,但不设置目录时间)。

同步到 FAT 分区,跳过软链接,处理 FAT 时间精度为2秒导致的问题:

rsync -rltDvi --modify-window=2 --delete ~/音乐/ --exclude-from=<(find ~/音乐/ -type l|cut -d/ -f5-) phone_usb:/sdcard/Music -n

MTP

rsync -virtOL --append-verify --inplace --delete SRC DEST

同步目标

SRC/结尾时,会将SRC下的内容同步到DEST(同步不同名目录)。当SRC是不以/结尾的目录时,将此目录同步到DESR下(同步同名目录)。同步普通文件时,可两者都指定文件名。

指定要同步的部分文件,排除其它的:

rsync -aviKhP --delete --include='*/' --exclude='*fastdfs*' --include='*.rpm' --exclude='*' --prune-empty-dirs SRC DEST

选项

指定要同步的文件数据

-u, --update
跳过更新的文件
--exclude=PATTERN
--size-only
同步时不考虑时间戳。当文件时间戳被意外改变(如生成拷贝时没有保留时间戳)有用,此时可同时不指定-t选项以避免更新时间戳。
--modify-window
允许的时间误差,以秒计
--files-from=FILE
指定要同步的文件。此时不递归目录,除非指定-r选项。列表中的路径相对于src-R),开头的/会被移除。
-R, --relative
将命令行上的路径全部在目的地重建(与mkdir -p不同的是,会复制路径的元信息)

以下两项数据没有包含在-a, --archive中:

-X, --xattrs
同步文件扩展属性
-A, --acls
同步文件访问控制表(ACL)

传输处理

-n, --dry-run
--partial
保留同步未完成的文件
--progress
显示进度
--inplace
直接修改文件(而不使用临时文件)
-P
等同于--partial--progress
-z
压缩传输的数据。比在 ssh 等传输层中压缩效率要高[1],所以使用 ssh 的话,最好同时关闭 ssh 的压缩。
-h
使用合适的单位显示数据大小

文件传输目的地

-t
保留修改时间
-O
忽略目录时间
--links
保留软链接
-L
跟从软链接
-K
将接收方的目标为目录的软链接视为目录
-H, --hard-links
保留硬链接
--delete-excluded
删除被排除的文件(会隐含--delete
--chmod=MODE
使用指定的权限覆盖,如1=--chmod=u=rwX,go=rX

rsync 服务

指定配置文件等:

rsync rsyncd --daemon --config=$HOME/etc/rsyncd.conf --bwlimit=1024 --port=2873

一个普通用户可用的配置文件示例:

port = 1873
use chroot = no

[data]
        path = /data
        dont compress = *
        hosts allow = 192.168.55.2

对端使用 rsync://host:port/module 的语法来同步。

注意事项与技巧

重命名

重命名会被识别为单独的添加和删除操作。

避免更新 atime

从 3.2.0 开始,rsync 支持使用 --atimes-U)选项来同步 atime,重复或者使用 --open-noatime 选项在读取文件时不更新 atime(也可以通过 mount 为只读来解决,如使用 bwrap)。

早期 rsync 版本有一个增加--noatime选项的补丁,Debian 版本的 rsync 自带。此选项不会默认传递给远端。需要在远端使用时需要使用-M手动指定,如

rsync -vi --noatime -M --noatime host:src dst

--inplace--sparse 不能同时使用

[2]

--delay-updates

该选项会创建 .~tmp~/ 临时目录(可通过选项改名)。有时候(据说是更新到一半时源端被更新就会出现,可以使用 --delete-excluded 删除[3])这个目录中有文件未能处理,下一次更新会导致相应的文件无法被更新。

使用特制的 shell

比如在远端使用 sudo

#!/usr/bin/env python3

import sys
import os

def main():
  args = sys.argv
  if args[1] == '-l':
    user = args[2]
    index = 3
  else:
    user = 'root'
    index = 1

  host = args[index]
  remote_cmd = args[index+1:]

  cmd = ['ssh', host, 'sudo', '-u', user] + remote_cmd
  os.execvp('ssh', cmd)

if __name__ == '__main__':
  main()

又如使用 strace 来调试:

#!/usr/bin/env python3

import sys
import os

def main():
  args = sys.argv
  if args[1] == '-l':
    user = args[2]
    index = 3
  else:
    user = 'lilydjwg'
    index = 1

  host = args[index]
  remote_cmd = args[index+1:]

  cmd = ['ssh', host, 'strace', '-f', '-o', '/tmp/strace.log'] + remote_cmd
  os.execvp('ssh', cmd)

if __name__ == '__main__':
  main()

参见

外部链接

参考资料