Sul posto estrarre l'archivio tar


14

Ho un piccolo dilemma qui ...

Avevo bisogno di spostare circa 70 GB di file da uno dei miei server a un altro, quindi ho deciso che rimuoverli e inviare l'archivio sarebbe stato il modo più veloce.

Tuttavia, il server ricevente ha solo 5 GB di spazio rimasto dopo aver ricevuto l'archivio tar.

Esiste un modo per estrarre il tar "sul posto"? Non ho bisogno di conservare l'archivio dopo che è stato estratto, quindi mi chiedevo se fosse possibile farlo.

Modifica: Va notato che l'archivio è già stato inviato e vorrei evitare di inviarlo nuovamente con un metodo diverso.

Risposte:


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

questo si traduce in:

  • tar e comprimi 'stuff_to_backup' in stdout
  • accedi a 'backupmachine' via ssh
  • esegui "tar" sul "backupmachine" e decomprimere il materiale proveniente da stdin

personalmente userei 'rsync over ssh' per trasferire le cose perché puoi continuare a trasferire le cose se la connessione si interrompe:

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

che trasferirà tutto da "stuff_to_backup" alla cartella "backup" su "backupmachine". se la connessione si interrompe, basta ripetere il comando. se alcuni file in "stuff_to_backup" cambiano, ripeti gli elementi, verrà trasferita solo la differenza.


Vedi la mia domanda modificata
codardo anonimo il

@Charlie Somerville: sì, hai lasciato fuori la parte importante in primo luogo. :)
Akira,

6

Se l'altra macchina ha ssh, ti consiglierei rsync come un'altra alternativa che non utilizza un file tar:

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

E stai attento con il leader /

Modifica aggiornamento

Bene, vedo come questo sia ora un ottimo sottaceto se non sei in grado di eliminarlo e ricominciare con rsync. Probabilmente proverei un estratto selettivo ed eliminerei dal tar.

estratto selettivo:

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

eliminazione selettiva:

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

Tuttavia, sembra che passerai molto tempo a scrivere uno script per questo ...


Vedi la mia domanda modificata
codardo anonimo il

Vedi la mia risposta modificata ... buona fortuna: - /
YuppieNetworking

Grazie per la modifica. I file sono effettivamente denominati con numeri, quindi un rapido ciclo in bash potrebbe fare il trucco.
codardo anonimo il

1
@Charlie Somerville: potresti dover iniziare con i file archiviati alla fine del tar, altrimenti potresti finire con tar creando un nuovo archivio ... quindi, prima cancella i file dalla fine del tar.
Akira,

5

Fondamentalmente, ciò di cui hai bisogno è la possibilità di convogliare il file in tar e "saltare" il fronte mentre procedi.

Su StackOverflow, qualcuno ha chiesto come troncare un file in primo piano , ma sembra che non sia possibile. Potresti ancora riempire gli zeri del file in modo speciale in modo che il file diventi un file sparse , ma non so come farlo. Tuttavia, possiamo troncare la fine del file. Ma tar deve leggere l'archivio in avanti, non all'indietro.

Soluzione 1

Un livello di riferimento indiretto risolve ogni problema. Prima inverti il ​​file sul posto, quindi leggilo all'indietro (il che comporterà la lettura del file originale in avanti) e troncare la fine del file invertito mentre procedi.

Dovrai scrivere un programma (c, python, qualunque cosa) per scambiare l'inizio e la fine del file, pezzo per pezzo, e poi reindirizzare questi pezzi a tar mentre troncando il file un pezzo alla volta. Questa è la base per la soluzione 2 che è forse più semplice da implementare.

Soluzione 2

Un altro metodo è quello di dividere il file in piccoli blocchi sul posto , quindi eliminare quei pezzi mentre li estraiamo. Il codice seguente ha una dimensione di blocco di un megabyte, regolare in base alle proprie esigenze. Più grande è più veloce ma occuperà più spazio intermedio durante la divisione e durante l'estrazione.

Dividi il file 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

Pipa quei file in tar (nota che abbiamo bisogno della variabile chunkprefix nel secondo terminale):

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.

Poiché utilizziamo una pipe denominata ( mkfifo fifo), non è necessario eseguire il pipe di tutti i blocchi contemporaneamente. Questo può essere utile se sei davvero limitato nello spazio. Puoi seguire i seguenti passi:

  • Sposta, ad esempio gli ultimi blocchi da 10 GB su un altro disco,
  • Inizia l'estrazione con i pezzi che hai ancora,
  • Al termine del while [ -e … ]; do cat "$chunk…; doneloop (secondo terminale):
  • NON interrompere il tarcomando, NON rimuovere il fifo (primo terminale), ma è possibile eseguire sync, nel caso,
  • Sposta alcuni file estratti che ritieni siano completi (tar non è bloccato in attesa che i dati finiscano di estrarre questi file) su un altro disco,
  • Sposta indietro i pezzi rimanenti,
  • Riprendi l'estrazione eseguendo di while [ -e … ]; do cat "$chunk…; donenuovo le linee.

Ovviamente questo è tutto haute voltige , ti consigliamo di controllare prima che tutto sia ok su un archivio fittizio, perché se commetti un errore allora addio dati .

Non saprai mai se il primo terminale ( tar) ha effettivamente terminato l'elaborazione del contenuto del fifo, quindi se preferisci puoi invece eseguirlo, ma non avrai la possibilità di scambiare senza problemi pezzi con un altro disco:

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

disconoscimento

Si noti che per far funzionare tutto ciò, la shell, la coda e il troncato devono gestire correttamente gli interi a 64 bit (per questo non è necessario un computer a 64 bit né un sistema operativo). Lo fa il mio, ma se esegui lo script sopra su un sistema senza questi requisiti, perderai tutti i dati in archive.tar .

E comunque qualcosa di diverso va storto, perderai comunque tutti i dati in archive.tar, quindi assicurati di avere un backup dei tuoi dati.


0

Se hai dei file oggetto da spostare, prova a rimuoverli. Ciò farà risparmiare una notevole quantità di spazio.

$ strip `find . -name "*.bin"`
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.