AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1094803
Accepted
TravisCarden
TravisCarden
Asked: 2022-02-26 11:07:59 +0800 CST2022-02-26 11:07:59 +0800 CST 2022-02-26 11:07:59 +0800 CST

rsync 具有自己后代的目录

  • 772

tl; dr:我想要rsync一个目录到它自己的后代,然后rsync将所述后代返回到原始目录——包括两个方向的删除和排除。

在你问一个明显的问题之前,“你为什么要这样做?” 或指出另一种方法会有多好,这是业务需求。这不是我的选择,我知道风险,所以放纵我。我不打算进一步证明这种方法的合理性。?

细节:

我想要rsync一个目录到它自己的后代 - 即,它“下面”或“内部”的目录,例如,然后将后代的更改同步回原始目录,例如parentto ,包括删除和两个方向的排除。在视觉上,我需要这样做:parent/childparent/childparent

parent -> parent/child
parent <- parent/child

困难在于...

  1. 从祖先到后代时防止无限递归
  2. 将后代同步回其祖先时,不会在操作中删除源文件(表现为“文件已消失”错误)
  3. 始终尊重例外情况
rsync
  • 2 2 个回答
  • 47 Views

2 个回答

  • Voted
  1. Best Answer
    TravisCarden
    2022-02-26T11:07:59+08:002022-02-26T11:07:59+08:00

    解决方案分为三个部分。为了...

    1. 排除相对于祖先的后代目录路径,例如,child从同步时parent/child
    2. 使用--delete-after标志而不是 --delete
    3. 使所有排除路径都相对于源,例如,exclude.txt与/var/www/parent/exclude.txt

    这是一个测试脚本(带有一些特殊格式以获得更好的输出):

    #!/usr/bin/env bash
    
    clear
    
    printf "\n\e[33mrsync version:\n"
    printf "%s--------------\e[39m\n"
    
    rsync --version | head -n 1
    # rsync  version 2.6.9  protocol version 29
    
    rm -r parent
    
    mkdir -p parent
    
    touch parent/original.txt \
          parent/delete-from-child.txt \
          parent/exclude-from-child.txt
    
    printf "\n\e[33mOriginal state:\n"
    printf "%s---------------\e[39m\n"
    
    tree -a --noreport -- parent
    
    printf "\n\e[33mrsync to child:\n"
    printf "%s---------------\e[39m\n"
    
    printf "rsync --archive \\n      --delete-after \\n      --exclude=exclude-from-child.txt \\n      "$PWD"/parent/ \\n      "$PWD"/parent/child\n\n"
    rsync --archive \
          --delete-after \
          --exclude=exclude-from-child.txt \
          "$PWD"/parent/ \
          "$PWD"/parent/child
    
    tree -a --noreport -- parent; echo
    
    printf "\e[33mMake changes:\n"
    printf "%s---------------\e[39m\n"
    
    rm parent/child/delete-from-child.txt
    printf "rm parent/child/delete-from-child.txt\n"
    touch parent/child/create-in-child.txt
    printf "touch parent/child/create-in-child.txt\n"
    touch parent/child/exclude-from-parent.txt
    printf "touch parent/child/exclude-from-parent.txt\n\n"
    
    printf "\e[33mrsync back to parent:\n"
    printf "%s---------------------\e[39m\n"
    
    printf "rsync --archive \\n      --delete-after \\n      --exclude=child \\n      --exclude=exclude-from-child.txt \\n      --exclude=exclude-from-parent.txt \\n      "$PWD"/parent/child/ \\n      "$PWD"/parent\n\n"
    rsync --archive \
          --delete-after \
          --exclude=child \
          --exclude=exclude-from-child.txt \
          --exclude=exclude-from-parent.txt \
          "$PWD"/parent/child/ \
          "$PWD"/parent
    
    tree -a --noreport -- parent; echo
    # Or `find parent -type f; echo`, if you don't have `tree`
    
    printf "%s\n\e[33mFinal comparison:\n"
    printf "%s-----------------\e[39m\n"
    
    diff --exclude=child parent parent/child; echo
    

    输出:

    rsync version:
    --------------
    rsync  version 2.6.9  protocol version 29
    
    Original state:
    ---------------
    parent
    ├── delete-from-child.txt
    ├── exclude-from-child.txt
    └── original.txt
    
    rsync to child:
    ---------------
    rsync --archive
          --delete-after
          --exclude=exclude-from-child.txt
          /var/www/parent/
          /var/www/parent/child
    
    parent
    ├── child
    │   ├── delete-from-child.txt
    │   └── original.txt
    ├── delete-from-child.txt
    ├── exclude-from-child.txt
    └── original.txt
    
    Make changes:
    ---------------
    rm parent/child/delete-from-child.txt
    touch parent/child/create-in-child.txt
    touch parent/child/exclude-from-parent.txt
    
    rsync back to parent:
    ---------------------
    rsync --archive
          --delete-after
          --exclude=child
          --exclude=exclude-from-child.txt
          --exclude=exclude-from-parent.txt
          /var/www/parent/child/
          /var/www/parent
    
    parent
    ├── child
    │   ├── create-in-child.txt
    │   ├── exclude-from-parent.txt
    │   └── original.txt
    ├── create-in-child.txt
    ├── exclude-from-child.txt
    └── original.txt
    
    
    Final comparison:
    -----------------
    Only in parent: exclude-from-child.txt
    Only in parent/child: exclude-from-parent.txt
    
    • 0
  2. András Korn
    2022-02-26T12:14:06+08:002022-02-26T12:14:06+08:00

    另一种方法是设置绑定挂载,从而使两棵树看起来独立,然后正常 rsync:

    mkdir /mnt/parent
    mkdir /mnt/child
    mkdir /mnt/empty
    mount --bind /path/to/parent/child /mnt/child
    mount --bind /path/to/parent /mnt/parent
    mount --bind /mnt/empty /mnt/parent/child
    

    现在,当你这样做时

    rsync [args] /mnt/parent/. /mnt/child/.
    

    空目录/mnt/empty将掩盖真实/path/to/parent/child目录;/mnt/parent/child将显示为空并避免无限递归。

    当你这样做

    rsync [args] /mnt/child/. /mnt/parent/.
    

    情况类似;/mnt/child/child/将是空的(因为您一开始没有复制任何内容),并且/mnt/parent/child/也将显示为空,因此没有从那里删除任何内容的风险。

    这可能不如@TravisCarden 的解决方案优雅,但可能更健壮。

    • 0

相关问题

  • 强制 rsync 进入非交互模式

  • 比较(diff)完整目录结构的最佳方法?

  • 如何使用 rsync 保持完整路径?

  • Rsyncing到USB驱动器时不时地失败

  • 使用 rsync 维护名称更改的目录的副本

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve