Linux

rsync:使用過濾器排除頂級目錄但包括其一些子目錄

  • March 4, 2019

我想用rsync備份我的/home目錄。我已閱讀 rsync 的手冊頁並決定為此任務使用過濾規則。

我想要實現的目標: 排除目錄中的所有文件和目錄,Repos但保留所有pull_all.sh文件和output目錄——無論它們位於Repos目錄中的什麼位置。

到目前為止,我最終得到了以下過濾器列表,但這僅備份pull_all.sh文件而不備份output目錄:

# Files prefixed with "+ " are included. Files prefixed with "- " are excluded.
#
# The order of included and excluded files matters! For instance, if a folder
# is excluded first, no subdirectory can be included anymore. Therefore,
# mention included files first. Then, mention excluded files.
#
# See section "FILTER RULES" of rsync manual for more details.


# Included Files

# TODO: This rules do not work properly!
+ output/***
+ pull_all.sh
- Repos/**

# Excluded Files

- .android
- .cache
...

我在腳本中使用過濾器列表run_rsync.sh

#!/bin/bash

date="$(date +%Y-%m-%d)"
hostname="$(hostname)"

# debug_mode="" # to disable debug mode
debug_mode="--list-only"

# Note: With trailing "/" at source directory, source directory is not created at destination.
rsync ${debug_mode} --archive --delete --human-readable --filter="merge ${hostname}.rsync.filters" --log-file=logfiles/$date-$hostname-home.log --verbose /home backup/

不幸的是,現有的 StackExchange 執行緒並沒有解決我的問題:

這裡出了什麼問題?

$$ Update $$以下是主目錄的外觀範例以及要保留哪些文件以及要忽略哪些文件:

user@hostname:~$ tree /home/ | head
/home/
└── user
   ├── Desktop                -> keep this
   │   ├── file1              -> keep this
   │   └── file2              -> keep this
   ├── Documents              -> keep this
   ├── Repos
   │   ├── pull_all.sh        -> keep this
       ├── subdir1
       │   ├── output         -> keep this
       ├── subdir2
           ├── another_subdir
               ├── output     -> keep this
       ├── subdir3            -> do not keep (because does not contain any "output")
       ├── file3              -> do not keep

稍微重申一下我解釋為您的要求,

  • 包括所有pull_all.sh文件,無論我們在哪裡找到它們
  • 包括所有output目錄及其內容,無論我們在哪裡找到它們
  • 排除Repos目錄,除了我們已經說過的
  • 包括其他所有內容

這可以指定如下

rsync --dry-run --prune-empty-dirs -av

   --include 'pull_all.sh'
   --include 'Repos/**/output/***'

   --include '*/'

   --exclude 'Repos/***'

   /home backup/

一些筆記

  • 是必需的--include '*/',以便rsync考慮向下進入Repos目錄樹(查找pull_all.sh文件),否則最終--exclude語句將排除這些目錄樹。

  • 的三種不同用途*是不同的:

    • *匹配除/字元以外的任何內容
    • **匹配任何內容,包括/字元
    • dir/***是等效於指定dir/and的快捷方式dir/**
  • --prune-empty-dirs標誌停止rsync創建空目錄,這在我們需要處理Repos目錄樹查找pull_all.shoutput項目時尤為重要。

  • --dry-run當您對結果滿意時刪除。

引用自:https://unix.stackexchange.com/questions/503270