回答:
% tar czf - stuff_to_backup | ssh backupmachine tar xvzf -
これは次のように翻訳されます:
私は個人的に「rsync over ssh」を使用してものを転送します。なぜなら、接続が切断された場合でもものを転送し続けることができるからです:
% rsync -ar --progress -e 'ssh' 'stuff_to_backup' user@backupmachine:/backup/
「stuff_to_backup」から「backupmachine」の「backup」フォルダーにすべてを転送します。接続が切断された場合は、コマンドを繰り返してください。'stuff_to_backup'の一部のファイルが変更された場合は、その内容を繰り返しますが、差分のみが転送されます。
他のマシンにsshがある場合、tarファイルを使用しない別の代替手段としてrsyncを使用することをお勧めします。
rsync -avPz /some/dir/ user@machine:/some/other/dir/
そして、先頭に注意してください /
更新を編集
さて、これを削除してrsyncを再開することができない場合、これがどのように素晴らしいピクルスになるかがわかります。たぶん、選択的な抽出を試みて、tarから削除するでしょう。
選択的抽出物:
$ tar xvf googlecl-0.9.7.tar googlecl-0.9.7/README.txt
googlecl-0.9.7/README.txt
選択的削除:
$ tar --delete --file=googlecl-0.9.7.tar googlecl-0.9.7/README.txt
ただし、このためのスクリプトのコーディングには多くの時間を費やすようです...
基本的に、必要なのは、ファイルをtarにパイプし、実行中にフロントを "lop"する可能性です。
StackOverflowで、誰かがfrontのファイルを切り捨てる方法を尋ねましたが、それは不可能なようです。ファイルがスパースファイルになるように、ファイルの先頭を特別な方法でゼロで埋めることもできますが、その方法はわかりません。ただし、ファイルの終わりを切り捨てることはできます。ただし、tarは逆方向ではなく、順方向にアーカイブを読み取る必要があります。
解決策1
レベルの間接化は、すべての問題を解決します。最初にファイルを元に戻し、次に逆方向に読み取り(元のファイルを順方向に読み取ります)、逆方向のファイルの末尾を切り捨てます。
ファイルの始まりと終わりをチャンクごとに交換するプログラム(c、pythonなど)を作成し、これらのチャンクをtarにパイプして、一度に1チャンクずつファイルを切り捨てる必要があります。これがソリューション2の基礎であり、実装がより簡単かもしれません。
解決策2
別の方法は、ファイルをインプレースで小さなチャンクに分割し、それらのチャンクを抽出するときに削除することです。以下のコードのチャンクサイズは1メガバイトですが、必要に応じて調整してください。大きいほど高速になりますが、分割時および抽出時に中間スペースが必要になります。
ファイルarchive.tarを分割します。
archive="archive.tar"
chunkprefix="chunk_"
# 1-Mb chunks :
chunksize=1048576
totalsize=$(wc -c "$archive" | cut -d ' ' -f 1)
currentchunk=$(((totalsize-1)/chunksize))
while [ $currentchunk -ge 0 ]; do
# Print current chunk number, so we know it is still running.
echo -n "$currentchunk "
offset=$((currentchunk*chunksize))
# Copy end of $archive to new file
tail -c +$((offset+1)) "$archive" > "$chunkprefix$currentchunk"
# Chop end of $archive
truncate -s $offset "$archive"
currentchunk=$((currentchunk-1))
done
これらのファイルをtarにパイプします(2番目のターミナルにchunkprefix変数が必要なことに注意してください)。
mkfifo fifo
# In one terminal :
(while true; do cat fifo; done) | tar -xf -
# In another terminal :
chunkprefix="chunk_"
currentchunk=0
while [ -e "$chunkprefix$currentchunk" ]; do
cat "$chunkprefix$currentchunk" && rm -f "$chunkprefix$currentchunk"
currentchunk=$((currentchunk+1))
done > fifo
# When second terminal has finished :
# flush caches to disk :
sync
# wait 5 minutes so we're sure tar has consumed everything from the fifo.
sleep 300
rm fifo
# And kill (ctrl-C) the tar command in the other terminal.
名前付きパイプ(mkfifo fifo
)を使用しているため、一度にすべてのチャンクをパイプする必要はありません。これは、スペースが本当に限られている場合に便利です。次の手順を実行できます。
while [ -e … ]; do cat "$chunk…; done
ループが終了した(第2端子)tar
コマンドを停止しないでください。fifo(最初の端末)を削除しないでください。ただし、念のためsync
、while [ -e … ]; do cat "$chunk…; done
行を再度実行して、抽出を再開します。もちろん、これはすべて高級電圧です。最初にダミーアーカイブですべてが正常であることを確認する必要があります。なぜなら、間違えた場合はデータをさようなら。
最初の端末(tar
)が実際にfifoのコンテンツの処理を完了したかどうかは分からないので、代わりにこれを実行することもできますが、別のディスクとチャンクをシームレスに交換することはできません。
chunkprefix="chunk_"
currentchunk=0
while [ -e "$chunkprefix$currentchunk" ]; do
cat "$chunkprefix$currentchunk" && rm -f "$chunkprefix$currentchunk"
currentchunk=$((currentchunk+1))
done | tar -xf -
免責事項
これがすべて機能するためには、シェル、テール、およびトランケートが64ビット整数を正しく処理する必要があることに注意してください(そのために64ビットコンピューターもオペレーティングシステムも必要ありません)。私のものですが、これらの要件のないシステムで上記のスクリプトを実行すると、archive.tarのすべてのデータが失われます。
いずれにしても、それ以外のことがうまくいかない場合は、とにかくarchive.tarのすべてのデータが失われるので、データのバックアップがあることを確認してください。