Backup

ssh & tar 增量傳輸(如 rsync)

  • November 15, 2009

在沒有 rsync 客戶端的託管環境中,我想執行類似於 rsync 所做的操作:僅發送那些已更改的文件。

我將在目前目錄上執行此單行。這將使用更改的文件更新 archive.tar.gz,然後將文件 scp 到遠端站點,最後將其解壓縮並保留同步目錄。我有使用多個管道的願景,但我想我需要一個存檔來實際使用增量功能。

使用增量時,我迷失了 tar 語法。

bozosync.sh

嗯,如果您只想移動更改的文件,為什麼 tar 命令會更新存檔?如果只發送更改的文件,那麼 tar 存檔不是只包含它們,因此每次都必須從頭開始重新創建嗎?

如果我理解正確,你想要這樣的東西,我稱之為bozosync.sh

TarFile=fun.tgz
TheScript=$0
result=
ls -1 . | (
 while read f; do
   if [ -f "$f" -a $f -nt $TheScript ]; then
     result="$result $f"
   fi
 done
 tar cvfz $TarFile $result
 touch $TheScript
)

這會將每個普通文件放在 tar 存檔的目前目錄中,對於每個比腳本本身更新的文件,然後它touch(1)在腳本上執行以更新其 mod 時間。這確實有一個競爭條件,因為在測試和触摸之間修改的文件將在下一次被忽略。如果這是一個問題,您可以通過在循環之前複製腳本,然後在最後將其移回自身來解決這個問題。(然後你仍然有比賽,但失敗更溫和,它可能只是包含一個沒有真正改變的文件。)

這是DigitalRoss腳本的修改版本:

#!/bin/bash
TarFile=fun.tgz
TheScript=$0
saveIFS="$IFS"
IFS=$'\n'
files=($( find -maxdepth 1 -type f -newer $TheScript -print ))
tmpfile=$(mktemp)
IFS="$saveIFS"
tar cvfz $TarFile "${files[@]}" && touch -r $tmpfile $TheScript
rm $tmpfile

這通過將結果保存在數組中並立即創建臨時文件來減少競爭條件的機會。find但這當然不能保證。此外,此腳本避免使用ls. 另一個優點是它僅在成功時更新腳本的時間戳tar。它還將處理帶有空格的文件名。

引用自:https://serverfault.com/questions/80720