題 使用本地驅動器上目錄的rsync創建差異備份到同一驅動器上的另一個目錄


我如何使用rsync(但既不是rsnapshot也不是rdiff-backup,也不是任何其他應用程序)來創建 微分 將本地驅動器上的目錄備份到同一本地驅動器上的另一個目錄?

F. Hauri在以下網站發布了以下內容 一個向下的人 如何創建本地備份?

#!/bin/bash
backRepo=/media/mydisk
backSrce=/home/user
backDest=home
backCopy=copy
backCount=9

[ -d "$backRepo/$backDest" ] || mkdir "$backRepo/$backDest"

cd $backSrce || exit 1
rsync -ax --delete --exclude '*~' --exclude '.DStore' . "$backRepo/$backDest/."

cd $backRepo
[ -d "$backCopy.$backCount" ] && rm -fR "$backCopy.$backCount"
for ((i=$backCount;i--;));do
    [ -d "$backCopy.$i" ] && mv "$backCopy.$i" "$backCopy.$((i+1))"
  done
((i++))

cp -al $backDest $backCopy.$i

看起來上面的劇本與我想要的相當接近,但坦率地說,儘管花了大約一個小時的時間學習 使用Linux和Rsync輕鬆實現自動快照式備份 我仍然只有一個模糊的想法,如何使rsync做我想要的。

這是我的用例:

我正在我的機器上本地編輯視頻。與該視頻相關的所有數百個文件的總和將小於5 GB(5千兆字節)。

目前,我使用Grsync將我的內部驅動器備份到外部USB驅動器。雖然我實際上想出瞭如何使用rsync完成相同的任務,但我更喜歡使用Grsync,因為我只需要啟動它然後單擊一個按鈕將包含我的視頻文件的內部目錄備份到外部USB驅動器。整個過程如絲般順滑。

每隔幾個小時,我就想要一個相當流暢的方式將上述與我的視頻相關的數據備份到我的Google雲端硬盤帳戶。我不介意手動選擇將文件夾上傳到Google雲端硬盤。我實際上更喜歡這樣做,因為它可以幫助我確保備份實際完成。

在我上床睡覺前的幾個晚上,我一直在復制包含視頻文件的整個文件夾,其中包含許多數據,直到我的Google雲端硬盤帳戶。

我更喜歡差異備份到增量備份,因為如果我需要從Google雲端硬盤恢復數據,我可能會手動執行此操作而不會感到困惑。

請記住,我當然不是支持數百名用戶的大型公司的unix系統管理員。我只是一個想要一個簡單的方法,但不一定是完全自動化的方法的人,每隔幾個小時在異地備份他的數據,以防萬一發生災難性的數據丟失,這很可能是由於我的計算機被盜。我幾乎可以肯定rsync可以做我想要的。因此,我不願意安裝另一個應用程序。


4
2017-09-21 08:17


起源




答案:


你去吧!

#!/bin/bash

# written by strobelight, you know who you are.
# license, MIT, go for it.

me=`basename $0`

EXCLUDES="\
    --exclude '*~'
    --exclude '.DS_Store'
"

CANDIDATES=/tmp/candidates

usage() {
    cat <<EOF

$me last_diff_dir new_diff_dir [ dir_to_copy ]

where:
    last_diff_dir  is the directory containing the last differential
    new_diff_dir   is the directory you want files saved to
    dir_to_copy    is optional and is the directory to copy from (default .)

cd directory_to_backup
Full backup: $me full_back full_back
Diff backup: $me full_back diff_1
Diff backup: $me full_back diff_2

EOF
    exit 1
}

get_dir() {
    HERE=`pwd`
    cd $1
    x=`pwd`
    cd $HERE
    echo $x
}

if [ $# -lt 2 ]; then
    usage
fi

LAST_DIR="$1"
NEW_DIR="$2"
DIR_TO_COPY="${3:-.}"

mkdir -p "$LAST_DIR" || exit 1
mkdir -p "$NEW_DIR" || exit 1

[ -d "$LAST_DIR" ] || usage
[ -d "$NEW_DIR" ] || usage
[ -d "$DIR_TO_COPY" ] || usage

LAST_DIR=`get_dir "$LAST_DIR"`
NEW_DIR=`get_dir "$NEW_DIR"`
DIR_TO_COPY=`get_dir "$DIR_TO_COPY"`

# get list of what's different
eval rsync -v --dry-run -axH --delete --update $EXCLUDES "$DIR_TO_COPY/" "$LAST_DIR" | awk '
    /building file list/ { next }
    /^$/ {next}
    /bytes.*received/ { nextfile }
    {
        for(i=5;i<NF;i++) {
            printf("%s ",$i)
        }
        printf("%s\n",$NF)
    }
    ' | sed 's:/$::' > $CANDIDATES
#cat $CANDIDATES

# use list to backup 
eval rsync --files-from=$CANDIDATES -lptgoDxH --delete $EXCLUDES ${DIR_TO_COPY}/ $NEW_DIR

例如,我當前的目錄有3個8k文件:

$ ls -1sk
total 24
 8 seg1
 8 seg2
 8 seg3

我的完整備份尚不存在,讓我們調用該目錄full_bak

ls ../full_bak
ls: ../full_bak: No such file or directory

首先,我們需要一個完整的備份來進行差異化。我已將腳本複製到我的$ HOME / bin目錄test123.sh。當兩個args相同時,它基本上執行完整備份。

$HOME/bin/test123.sh ../full_bak ../full_bak

腳本輸出

.
seg1
seg2
seg3

現在看看../full_bak

$ ls -1sk ../full_bak
total 24
 8 seg1
 8 seg2
 8 seg3

做一些改變

dd if=/dev/zero of=seg2 bs=512 count=11

確認存在差異:

$ diff -q . ../full_bak
Files ./seg2 and ../full_bak/seg2 differ

現在創建一個差異

$ $HOME/bin/test123.sh ../full_bak ../differential1
seg2

查看僅具有與上次完全備份不同的文件的差異

$ ls -1sk ../differential1/
total 8
 8 seg2

做出另一個改變

dd if=/dev/zero of=seg4 bs=512 count=10

檢查有什麼不同

diff -q . ../full_bak
Files ./seg2 and ../full_bak/seg2 differ
Only in .: seg4

並且看到我們有一個不在我們的完整備份中的新文件,以及之前更改的文件。

對另一個目錄執行另一個差異

$ $HOME/bin/test123.sh ../full_bak ../differential2
.
seg2
seg4

並看到新的差異有第一差異以及新文件

$ ls -1sk ../differential2
total 16
 8 seg2
 8 seg4

差異備份

這是使用test123.sh的fullbackup包裝器:

#!/bin/bash

FULLDIR=/media/mydisk/home
SRCDIR=/home/user

$HOME/bin/test123.sh $FULLDIR $FULLDIR $SRCDIR

這是一個基於小時創建子目錄的差異腳本:

#!/bin/bash

FULLDIR=/media/mydisk/fullbackup/home
DIFFDIR=/media/mydisk/differentials/home
SRCDIR=/home/user
DIFFSUB=`date '+BAK_%H'`

$HOME/bin/test123.sh $FULLDIR $DIFFDIR/$DIFFSUB $SRCDIR

0
2017-09-22 04:23



嗨@Strobelight,非常感謝。我花了大約半個小時試圖了解該做什麼並試圖去做,但我失敗了。我將您的腳本保存為我的主目錄中的“testing123.sh”。我導航到Properties-> Permissions for testing123.sh並選中“允許此文件作為程序運行”旁邊的複選框。在我的主目錄中,我創建了這些目錄:last_diff_dir,new_diff_dir和dir_to_copy。我把文件放到dir_to_copy中。我跑了tests123.sh。然後我檢查了new_diff_dir。它是空的。我希望你能幫助我。謝謝, - Yekutiel
如果上面註釋中附加到您姓名的逗號阻止您收到通知,我在沒有逗號的情況下添加了此註釋。 - Yekutiel
嗨@Yekutiel,基於你的評論,你會發現你使用的是Windows而不是linux。必須通過命令提示符運行該腳本。運行沒有args的腳本會顯示幫助。您無需創建所需的目錄。幫助顯示了一些用法。您需要至少創建一次完整備份,這是通過傳入與第2個args相同的目錄來完成的。第3個arg是您要備份的目錄,並且是可選的,因為它默認使用當前目錄。第一個2 args不應該是備份目錄中的目錄。希望有所幫助。 - strobelight
嗨@strobelight。感謝您的及時和詳細的回复。我正在運行Linux(GalliumOS 2.0運行在Xubuntu之上)。我還是很困惑。我經常運行...#!/ bin / sh gnome-screensaver-command --lock ...來自類似於我指示運行testing123.sh的方式的GUI。我使用名為Grsync的應用程序將rsync備份到外部USB。在Grsync中我可以選擇查看以下內容... rsync -r -t -v --progress --delete -s / home / y / test / input / home / y / test / output ...然後復制和粘貼到終端。但我更喜歡使用GUI。請ELI5從開始到完成一個假設的例子。謝謝! - Yekutiel
我想澄清我的倒數第二條評論。對於我要求的ELI5假設,我不需要GUI。相反,我很樂意在終端中運行它們。我可以通過CLE獲得OK。但是GUI只是在我的腦海里工作得更好,因為雖然我以一種精確的邏輯方式思考,但我不認為“在數學中”,我認為“在圖片中”。它曾用來驅動我瘋狂工作的開發人員。他們會說“2 + 2 = 4”之類的東西。然後我回答說:“哦。我明白了。如果你有兩棵樹和兩棵樹,那麼你總共有四棵樹。它們是獨自站立還是在森林裡?”他們會說,“是的.2 + 2 = 4” - Yekutiel