Yerinde katran arşivi yerinde


14

Burada küçük bir ikilem var ...

Sunucularımdan diğerine yaklaşık 70 GB değerinde dosya taşımam gerekiyordu, bu yüzden onları tartıp arşivi göndermenin en hızlı yol olduğuna karar verdim.

Ancak alıcı sunucu, tar arşivini aldıktan sonra yalnızca 5 GB alan kaldı.

Katranı 'yerinde' çıkarmanın bir yolu var mı? Arşivi çıkardıktan sonra arşivi tutmam gerekmiyor, bu yüzden bunun mümkün olup olmadığını merak ediyordum.

Düzenleme: Arşiv zaten gönderildi ve farklı bir yöntemle yeniden göndermek önlemek istiyorum.

Yanıtlar:


11
% tar czf - stuff_to_backup | ssh backupmachine tar xvzf -

bu şu anlama gelir:

  • tar ve stdout'a 'stuff_to_backup' öğesini sıkıştır
  • ssh üzerinden 'backupmachine' oturum açın
  • 'backupmachine' üzerinde 'tar' çalıştırın ve stdin'den gelen şeyleri untar

Ben şahsen bağlantı koparsa şeyler aktarmaya devam edebilirsiniz çünkü şeyler aktarmak için 'ss üzerinden rsync' kullanırdım:

% rsync -ar --progress -e 'ssh' 'stuff_to_backup' user@backupmachine:/backup/

her şeyi 'stuff_to_backup' öğesinden 'backupmachine' klasöründeki 'backup' klasörüne aktaracaksınız. bağlantı koparsa, komutu tekrarlamanız yeterlidir. 'stuff_to_backup' içindeki bazı dosyalar değişirse, öğeleri tekrarlayın, yalnızca fark aktarılacaktır.


Düzenlenmiş sorumu görün
anonim korkak

@Charlie Somerville: evet, önemli kısmı ilk etapta bıraktınız. :)
akira

6

Diğer makinede ssh varsa, rsync'i bir tar dosyası kullanmayan başka bir alternatif olarak öneririm:

rsync -avPz /some/dir/ user@machine:/some/other/dir/

Ve liderlere dikkat et /

Güncellemeyi düzenle

Eğer silmek ve rsync ile tavsiye edemiyorsanız, şimdi bu nasıl büyük bir turşu olduğunu görüyorum. Muhtemelen seçici bir özü dener ve katrandan silerim.

seçici özü:

$ tar xvf googlecl-0.9.7.tar googlecl-0.9.7/README.txt
googlecl-0.9.7/README.txt

seçici silme:

$ tar --delete --file=googlecl-0.9.7.tar googlecl-0.9.7/README.txt

Ancak, bunun için bir senaryo kodlamak için çok zaman harcayacağınız anlaşılıyor ...


Düzenlenmiş sorumu görün
anonim korkak

Düzenlenmiş cevabımı görün ... iyi şanslar: - /
YuppieNetworking

Düzenleme için teşekkürler. Dosyalar aslında sayılarla adlandırılır, bu yüzden bash'daki bir döngü hızlı bir şekilde hile yapabilir.
anonim korkak

1
@Charlie Somerville: katranın sonunda saklanan dosyalarla başlamanız gerekebilir, aksi takdirde katranla yeni bir arşiv oluşturabilirsiniz ... bu nedenle, önce tar'nın sonundaki dosyaları silin.
akira

5

Temel olarak, ihtiyacınız olan şey dosyayı katran içine borulama ve gittikçe ön "lop" olasılığıdır.

StackOverflow'da, birisi önündeki bir dosyayı nasıl kısaltacağını sordu , ancak bu mümkün değil gibi görünüyor. Dosyanın başlangıcını özel bir şekilde sıfırlarla doldurabilirsiniz, böylece dosya seyrek bir dosya olur , ancak bunu nasıl yapacağımı bilmiyorum. Yine de dosyanın sonunu kesebiliriz. Ancak katranın arşivi geriye doğru değil, ileriye doğru okuması gerekiyor.

Çözüm 1

Bir dolaylılık düzeyi her sorunu çözer. Önce dosyayı yerinde ters çevirin, ardından geriye doğru okuyun (orijinal dosyayı ileriye doğru okumanızla sonuçlanır) ve geri yüklenen dosyanın sonuna gittiğinizde kısaltın.

Dosyanın başlangıcını ve sonunu değiştirmek için bir program (c, python, ne olursa olsun) yazmanız, yığın tarafından yığınlandırmanız ve daha sonra dosyayı bir kerede bir parçayı keserken katranlara boru atmanız gerekir. Bu, uygulanması daha basit olan çözüm 2'nin temelidir.

Çözüm 2

Başka bir yöntem, dosyayı yerinde küçük parçalar halinde bölmektir , daha sonra bunları çıkardığımızda sileriz. Aşağıdaki kod, bir megabayt boyutundadır, ihtiyaçlarınıza göre ayarlayın. Daha büyük daha hızlıdır, ancak ayrılırken ve ekstraksiyon sırasında daha fazla ara alan gerektirir.

Archive.tar dosyasını bölün:

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

Bu dosyaları katran içine ekleyin (ikinci terminalde chunkprefix değişkenine ihtiyacımız olduğunu unutmayın):

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.

Adlandırılmış bir pipe ( mkfifo fifo) kullandığımız için , tüm parçaları bir kerede borulamak zorunda değilsiniz. Alanda gerçekten sıkıysanız bu yararlı olabilir. Aşağıdaki adımları takip edebilirsiniz:

  • Taşı, son 10Gb'lik parçanın başka bir diske söyle,
  • Çıkarmaya hala sahip olduğunuz parçalarla başlayın,
  • Zaman while [ -e … ]; do cat "$chunk…; donedöngü bittikten (ikinci uç):
  • tarKomutu DURDURMAYIN, fifo'yu (ilk terminal) ÇIKARMAYIN , ancak her syncihtimale karşı,
  • Tamamlandığını bildiğiniz bazı çıkarılan dosyaları (tar, verilerin bu dosyaları çıkarmayı bitirmesini beklerken durmaz) başka bir diske taşıyın,
  • Kalan parçaları geri taşı,
  • while [ -e … ]; do cat "$chunk…; doneHatları tekrar çalıştırarak ekstraksiyona devam edin .

Tabii ki bu tüm haute voltige , önce kukla bir arşivde her şeyin yolunda olduğunu kontrol etmek isteyeceksiniz, çünkü bir hata yaparsanız elveda veri .

İlk terminalin ( tar) aslında fifonun içeriğini işleyip işlemediğini asla bilemezsiniz , bu yüzden bunu tercih ederseniz bunun yerine parçaları başka bir diskle sorunsuz bir şekilde değiştirme olanağınız olmaz:

chunkprefix="chunk_"
currentchunk=0
while [ -e "$chunkprefix$currentchunk" ]; do
    cat "$chunkprefix$currentchunk" && rm -f "$chunkprefix$currentchunk"
    currentchunk=$((currentchunk+1))
done | tar -xf -

feragat

Tüm bunların çalışması için kabuğunuzun, kuyruğunuzun ve kesmenin 64 bit tamsayıları doğru şekilde işlemesi gerektiğini unutmayın (bunun için 64 bit bilgisayara veya işletim sistemine ihtiyacınız yoktur). Benimki, ancak yukarıdaki komut dosyasını bu gereksinimleri olmayan bir sistemde çalıştırırsanız, archive.tar içindeki tüm verileri kaybedersiniz .

Her halükarda bunun dışında bir şey ters giderse, yine de archive.tar içindeki tüm verileri kaybedersiniz, bu nedenle verilerinizin bir yedeğine sahip olduğunuzdan emin olun.


0

Taşınacak nesne dosyalarınız varsa, bunları soymayı deneyin. Bu, önemli miktarda yer tasarrufu sağlayacaktır.

$ strip `find . -name "*.bin"`
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.