Como criar um arquivo tar dividido em vários estágios para economizar espaço?

Jan 08 2021

Tenho uma pasta muito grande da qual estou tentando criar um arquivo tar. O problema é que não tenho espaço livre extra suficiente para armazenar todo o arquivo, então quero criar, digamos, pedaços de 100-200 GB do arquivo por vez e transferi-los individualmente para o armazenamento em nuvem. Preciso ser capaz de controlar quando novos pedaços são criados para que meu HDD não encha, mas todos os comandos que encontrei para criar tarballs divididos sempre criam tudo de uma vez, no mesmo diretório.

A solução mais próxima que encontrei foi a partir desta pergunta, mas todas as respostas baseiam os arquivos no número de arquivos, não no tamanho, o que é importante para o meu caso de uso, pois os tamanhos dos meus arquivos são distribuídos de forma desigual.

Respostas

2 EduardoTrápani Jan 08 2021 at 10:09

Você pode usar tar, com estas opções:

--new-volume-script=COMMAND
--tape-length=N

Ao final de cada volume ele chamará seu script, que terá algumas variáveis ​​de ambiente para saber qual volume acabou de ser processado. Verifique a página de manual para a lista completa, mas pelo menos a variável TAR_VOLUME é muito útil, caso você precise renomear o arquivo de saída ou manter o controle do volume atual:

TAR_VOLUME Número ordinal do tar de volume em processamento (definido se estiver lendo um arquivo de vários volumes).

Se o retorno do script 0 tarcontinuar, caso contrário, ele irá parar.

Por exemplo, isso criará cada volume, com um tamanho máximo de 20M, chamando seu script cada vez que o limite for atingido:

tar cvf /tmp/volume.tar /path/to/files/ --new-volume-script=/path/to/myscript.sh --tape-length=20M

O script pode ser um simples echo "Next volume";readou você pode até fazer a transferência dele (renomeando o volume, pois assim que sair /tmp/volume.tarserá sobrescrito).

Por outro lado, certifique-se de usar a sinalização --multi-volume. Se não o fizer, o tar irá parar com os erros (deixo-o para o caso de alguém procurar o erro):

tar: EOF inesperado no arquivo

tar: Erro não recuperável: saindo agora

tar xvf /path/to/transferred.volume --multi-volume

Prepare o volume 2 para /path/to/transferred.volume e pressione return:

tarsolicitará o novo volume. Assim que você pressionar enter /path/to/transferred.volume, será aberto novamente e assim por diante.

1 JoshHarrison Jan 09 2021 at 01:30

Seguindo a excelente resposta de eduardo-trápani , abaixo está uma versão ligeiramente modificada de um script encontrado na página GNU que espera a entrada do usuário para cada volume e tenta novamente se um volume não for encontrado:

Para completar, este é o comando usado para criar o arquivo:

tar cvf /tmp/volume.tar /path/to/files/ --new-volume-script=./myscript.sh --tape-length=1000M

E este é o comando que usei para extrair o arquivo dividido:

tar xvf /tmp/volume.tar --multi-volume --new-volume-script=./myscript.sh

myscript.sh:

#!/bin/bash
# For this script it's advisable to use a shell, such as Bash,
# that supports a TAR_FD value greater than 9.

echo "Press enter to continue to next volume"

read

echo Preparing volume $TAR_VOLUME of $TAR_ARCHIVE.

name=`expr $TAR_ARCHIVE : '\(.*\)-.*'` case $TAR_SUBCOMMAND in
-c)       ;;
-d|-x|-t) test -r ${name:-$TAR_ARCHIVE}-$TAR_VOLUME || echo "Failed to find volume" ;; *) exit 1 esac echo ${name:-$TAR_ARCHIVE}-$TAR_VOLUME >&$TAR_FD

Edit: Isso só funciona com GNU Tar, que pode ser instalado no macOS (w / Homebrew) por:

brew install gnu-tar

Para usá-lo como seu tar padrão, você precisará adicioná-lo ao seu caminho da seguinte forma:

export PATH="$(brew --prefix)/opt/python/libexec/bin:$PATH"