Artigo original: The Tar Command in Linux: Tar CVF and Tar XVF Explained with Example Commands

O nome tar é, de acordo com a maior parte dos relatos, uma abreviação para tape archive (arquivo de fitas, em português). As "fitas" em questão seriam todas aquelas unidades de armazenamento magnético que eram populares na década de 1950.

Isso sugere que a ferramenta tar pode ser um pouco antiga e ter passado de seu auge. A verdade, porém, é que, ao longo de todos os anos e passando por todas as mudanças sísmicas que ocorreram no mundo da TI, o tar não perdeu em nada o seu poder e valor.

Neste artigo, com base no conteúdo do meu livro Linux in Action (em inglês), vou mostrar os conceitos básicos de criação, compactação e restauração de arquivos tar. Comecemos pelo início.

Criação de arquivos

Este exemplo pegará todos os arquivos e diretórios dentro e sob o diretório de trabalho atual e criará um arquivo que chamei, inteligentemente, de nomedoarquivo.tar.

Aqui eu uso três argumentos após o comando tar:

  • c diz ao tar para criar um arquivo,
  • v define o resultado em tela como extenso (do inglês, verbose) para que eu obtenha as atualizações, e
  • f aponta para o nome do arquivo que eu desejo dar ao arquivo.

O * informa ao tar que ele deve incluir todos os arquivos e diretórios locais de modo recursivo.

$ tar cvf nomedoarquivo.tar *
arquivo1
arquivo2
arquivo3
diretorio1
diretorio1/maiscoisas
diretorio1/maiscoisas/arquivo100
diretorio1/maiscoisas/arquivo101

O comando tar nunca moverá ou excluirá nenhum dos diretórios e arquivos originais com os quais você o alimentou – ele só faz cópias arquivadas.

Você também deve observar que o uso de um ponto (.) em vez de um asterisco (*) no comando anterior incluiria até mesmo arquivos ocultos (cujos nomes de arquivos começam com um ponto) no arquivo.

Se você estiver acompanhando em seu próprio computador (como você definitivamente deveria estar fazendo), verá um novo arquivo chamado nomedoarquivo.tar. A extensão de nome de arquivo .tar não é necessária, mas é sempre uma boa ideia comunicar claramente o propósito de um arquivo de tantas maneiras quantas possível.

Extrair seu arquivo para restaurar os arquivos é fácil: basta usar xvf em vez de cvf. Isso, no exemplo, salvará novas cópias dos arquivos e diretórios originais no local atual.

$ tar xvf nomedoarquivo.tar
arquivo1
arquivo2
arquivo3
diretorio1
diretorio1/maiscoisas
diretorio1/maiscoisas/arquivo100
diretorio1/maiscoisas/arquivo101

Claro, você também pode pedir ao tar que envie seus arquivos extraídos para outro lugar usando o argumento -C, seguido do local de destino:

$ tar xvf nomedoarquivo.tar -C /home/meusdados/arquivosantigos/

Nem sempre você vai querer incluir todos os arquivos de uma árvore de diretório em seu arquivo.

Suponha que você tenha produzido alguns vídeos, mas eles são atualmente mantidos em diretórios junto com todos os tipos de arquivos gráficos, de áudio e de texto (contendo suas notas). Os únicos arquivos de que você precisa fazer o back-up são os clipes do vídeo final usando a extensão de nome de arquivo .mp4.

Fazemos isso assim:

$ tar cvf nomedoarquivo.tar *.mp4

Fantástico. Esses arquivos de vídeo, no entanto, são enormes. Não seria bom tornar esse arquivo um pouco menor usando a compactação?

Seu pedido é uma ordem! Basta executar o comando anterior com o argumento z (zip). Isso dirá ao programa gzip para compactar o arquivo.

Se você quiser seguir a convenção, também pode adicionar uma extensão .gz, além da extensão .tar, que já está lá. Lembre-se: clareza.

Seria assim:

$ tar czvf nomedoarquivo.tar.gz *.mp4

Se você tentar isso em seus próprios arquivos .mp4 e se, em seguida, executar ls -l no diretório que contém os novos arquivos, você pode notar que o arquivo .tar.gz não é muito menor do que o arquivo .tar, talvez 10% ou mais. Para que fazer isso, então?

Bem, o formato de arquivo .mp4 é compactado. Assim, há muito menos espaço para o gzip fazer sua mágica.

Como o tar está totalmente ciente de seu ambiente Linux, você pode usá-lo para selecionar arquivos e diretórios que vivem fora do diretório de trabalho atual. Este exemplo adiciona todos os arquivos .mp4 no diretório /home/meuusuario/Videos/:

$ tar czvf nomedoarquivo.tar.gz /home/meuusuario/Videos/*.mp4

Como os arquivos podem ficar grandes, às vezes, pode fazer sentido dividi-los em vários arquivos menores, transferi-los para sua nova casa e, em seguida, recriar o arquivo original na outra extremidade. A ferramenta de divisão é feita para este fim.

Neste exemplo, -b diz ao Linux para dividir o arquivo nomedoarquivo.tar.gz em partes de 1 GB. Em seguida, a operação nomeia cada uma das partes — nomedoarquivo.tar.gz.partaa, nomedoarquivo.tar.gz.partab, nomedoarquivo.tar.gz.partac e assim por diante:

$ split -b 1G nomedoarquivo.tar.gz "nomedoarquivo.tar.gz.part"

Por outro lado, você recria o arquivo lendo cada uma das partes em sequência (cat nomedoarquivo.tar.gz.part*) e, em seguida, redireciona a saída para um novo arquivo chamado nomedoarquivo.tar.gz:

$ cat nomedoarquivo.tar.gz.part* > nomedoarquivo.tar.gz

Utilizando a stream de arquivos do sistema de arquivos

É aqui que a parte boa começa. Vou mostrar como criar uma imagem de arquivo a partir de uma instalação do Linux em funcionamento e transmiti-la para um local de armazenamento remoto — tudo dentro de um único comando. Aqui está o comando:

# tar czvf - --one-file-system / /usr /var \
  --exclude=/home/andy/ | ssh username@10.0.3.141 \
  "cat > /home/nomedousuario/workstation-backup-Apr-10.tar.gz"

Em vez de tentar explicar tudo isso imediatamente, vou usar exemplos menores para explorar o comando aos poucos.

Vamos criar um arquivo de conteúdo de um diretório chamado coisasimportantes que está cheio de, você adivinhou, coisas realmente importantes:

$ tar czvf - coisasimportantes/ | ssh nomedousuario@10.0.3.141 "cat > /home/nomedousuario/meusarquivos.tar.gz"
coisasimportantes/arquivo1
coisasimportantes/arquivo2
[...]
nomedousuario@10.0.3.141's password:

Vamos explicar esse exemplo. Em vez de digitar o nome do arquivo logo após os argumentos de comando (da maneira que você fez até agora), usei um traço (czvf -).

O traço gera dados para a saída padrão. Ele permite que você envie os detalhes do nome do arquivo de volta para o final do comando e diz ao tar para esperar o conteúdo de origem para o arquivo.

Em seguida, usei um pipe (|) para enviar o arquivo compactado e sem nome para um login de ssh em um servidor remoto onde me foi pedida a minha senha.

O comando entre aspas executou cat no stream de dados do arquivo, que gravou o conteúdo do fluxo (do inglês, stream) em um arquivo chamado meusarquivos.tar.gz no meu diretório home no host remoto.

Uma vantagem de gerar arquivos dessa maneira é que você evita a sobrecarga de uma etapa intermediária. Não há necessidade de salvar temporariamente uma cópia do arquivo na máquina local. Imagine fazer back-up de uma instalação que ocupa 110 GB de seus 128 GB de espaço disponível. Para onde vai o arquivo?

Isso era apenas um diretório de arquivos. Suponha que você precise fazer o back-up de um sistema operacional Linux ativo em uma unidade USB para poder movê-lo para uma máquina separada e soltá-lo na unidade principal dessa máquina.

Supondo que já haja uma nova instalação da mesma versão do Linux na segunda máquina, a próxima operação de copiar/colar gerará uma réplica exata da primeira.

OBSERVAÇÃO: isso não funcionará em uma unidade de destino que não tenha um sistema de arquivos do Linux instalado. Para lidar com a situação, você precisará usar dd.

O próximo exemplo cria um arquivo compactado em uma unidade USB, conhecida como /dev/sdc1.

O argumento --one-file-system exclui todos os dados de qualquer sistema de arquivos que não seja o atual. Isso significa que as pseudopartições, como /sys/ e /dev/, não serão adicionadas ao arquivo. Se houver outras partições que você deseja incluir (como /usr/ e /var/, neste exemplo), elas devem ser adicionadas explicitamente.

Por fim, você pode excluir dados do sistema de arquivos atual usando o argumento --exclude:

# tar czvf /dev/sdc1/workstation-backup-Apr-10.tar.gz \
  --one-file-system \
  / /usr /var \
  --exclude=/home/andy/

Voltemos ao exemplo do comando de serviço completo. Usando o que você já aprendeu, arquive todos os diretórios importantes de um sistema de arquivos e copie o arquivo para uma unidade USB. Isso deve fazer sentido para você agora:

# tar czvf - --one-file-system / /usr /var \
  --exclude=/home/andy/ | ssh nomedousuario@10.0.3.141 \
  "cat > /home/nomedousuario/workstation-backup-Apr-10.tar.gz"

Há muito mais coisas interessantes em termos de administração do seu sistema, na forma de livros, cursos e artigos disponíveis no site do autor, bootstrap-it.com (em inglês).