Acabei de fazer backup do cartão microSD do meu Raspberry Pi no meu PC executando uma distribuição Linux usando este comando:
dd if=/dev/sdx of=file.bin bs=16M
O cartão microSD está apenas 3/4 cheio, então suponho que haja alguns shows de bytes nulos no final do tremendo arquivo. Tenho certeza de que não preciso disso. Como posso retirar esses bytes nulos do final de forma eficiente para que eu possa restaurá-los posteriormente com este comando?
cat file.bin /dev/zero | dd of=/dev/sdx bs=16M
Para criar uma cópia de backup de um disco enquanto economiza espaço, use
gzip
:Quando você quiser restaurar o disco do backup, use:
Isso provavelmente economizará muito mais espaço do que simplesmente remover os bytes NUL à direita.
Removendo bytes NUL à direita
Se você realmente deseja remover bytes NUL à direita e possui GNU sed, tente:
Isso pode ser um problema se os dados de um disco grande excederem algum limite interno de sed. Embora o GNU sed não tenha um limite embutido no tamanho dos dados, o manual do GNU sed explica que as limitações de memória do sistema podem impedir o processamento de arquivos grandes:
Você pode escrever uma ferramenta simples para resolver esse problema.
Leia o arquivo, descubra o último byte válido (não nulo) e trunque o arquivo.
Um exemplo em ferrugem de https://github.com/zqb-all/cut-trailing-bytes :
Eu tentei o comando de John1024
sed
e funcionou na maioria das vezes, mas para alguns arquivos grandes ele não cortou corretamente. O seguinte sempre funcionará:Observe que isso carrega o arquivo na memória primeiro. Você pode evitar isso escrevendo um script Python adequado que processe o arquivo em partes.
Prefácio
Acabei de resolver esse problema sozinho com o Python. É simples na teoria, mas na prática requer um pouco de código para funcionar corretamente. Eu queria compartilhar meu trabalho aqui para que outros não tenham que descobrir isso sozinhos.
O jeito simples (ruim)
O método mais simples (publicado anteriormente por letmaik) é carregar o arquivo na memória como uma string de bytes, usar o Python
.rstrp()
para remover bytes nulos à direita da bytestring e, em seguida, salvar essa bytestring sobre o arquivo original.Isso provavelmente funcionará na maioria das vezes, supondo que o arquivo seja menor que a memória disponível do sistema. Mas com arquivos maiores (32+ GB) ou em sistemas com menos RAM (Raspberry Pi), o processo travará o computador ou será encerrado pelo gerenciador de memória do sistema.
O Caminho Difícil (Correto)
A única maneira de contornar o problema de memória limitada é carregar um pequeno bloco de dados por vez, processá-lo, excluí-lo da memória e repetir no próximo pequeno bloco até que todo o arquivo seja processado. Normalmente dá para fazer isso em python com código bem compacto, mas como precisamos processar em blocos a partir do final do arquivo, voltando, dá um pouco mais de trabalho.
Eu fiz o trabalho para você. Aqui está:
Como você pode ver, são necessárias muito mais linhas de código, mas se você está lendo isso, essas linhas não precisam ser escritas agora! De nada. :)
Eu testei esta função usando arquivos de 4+ GB em um Raspberry Pi com 1 GB de RAM, e o processo nunca usou mais memória do que 50 MB no total. Demorou um pouco para processar, mas funcionou perfeitamente.
Conclusão
Ao programar, lembre-se de quantos dados você está carregando na memória a qualquer momento. Tenha em mente o maior tamanho de arquivo potencial com o qual você trabalhará e os limites inferiores potenciais da memória disponível para você.
Espero que isso ajude alguém na linha!
Pelo menos no Linux (e em sistemas de arquivos que o suportam, como o ext4 moderno), você pode usar
fallocate -d
para substituir essa sequência de zeros por buracos que não ocupam espaço em disco:Arquivo grande de 2GiB ocupando 2GiB de espaço em disco.
Mesmo arquivo grande de 2GiB, mas agora ocupando apenas 12KiB de espaço em disco.
Você pode remover o orifício à direita com:
O último bloco agora deve conter dados:
Embora você também possa remover os zeros à direita no último bloco, observe que isso não economizará espaço no disco.
Observe que não é porque 3/4 de um sistema de arquivos não está alocado que os blocos correspondentes do dispositivo de armazenamento subjacente conterão zeros. Se alguns arquivos foram gravados antes, mas excluídos desde então, os dados antigos ainda estarão lá, apenas os blocos correspondentes serão marcados como não alocados na estrutura do sistema de arquivos.
Uma exceção a isso pode ser se o suporte TRIM/DISCARD estiver disponível no dispositivo de bloco e for usado quando os sistemas de arquivos forem montados.
No Linux, os
loop
dispositivos suportam o corte e criarão um buraco correspondente no arquivo que faz o loop se for suportado pelo sistema de arquivos subjacente, para que você possa montar o sistema de arquivos em sua imagem:E faça um:
Para descartar os blocos não alocados do sistema de arquivos.
Se a imagem for particionada:
Em seguida, monte a
/dev/loopXpY
(s) partição(ões) correspondente(s).Você também pode querer ver coisas como
partimage
fazer um dump do seu cartão SD. O que cuidará apenas do despejo dos bits alocados.Usar
zerofree
no sdcard antes de despejar também garantiria que as partes não alocadas fossem preenchidas com zeros.