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…; done
loop (secondo terminale):
- NON interrompere il
tar
comando, 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…; done
nuovo 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.