Estou usando du
para monitorar continuamente a quantidade de dados gravados em unidades USB que estou duplicando.
Comparo o uso do disco das unidades de origem e de destino e exibo o progresso da cópia para o usuário.
O problema é que du
relata 100% dos dados presentes na unidade de destino, embora eu veja que muitos dados ainda estão no cache do sistema, o LED da unidade está piscando e as unidades não estão prontas para serem removidas.
Eu corro rsync
e sync
em umount
sequência para garantir que os dados realmente estejam lá antes de permitir que o usuário remova a unidade de destino. No entanto , não consigo monitorar o sync
progresso. Assim, o usuário verá 100% muito antes de as unidades serem realmente sincronizadas.
Eu adoraria poder monitorar o progresso "real" da cópia, pois é o que realmente importa - não adianta ver rsync
a cópia completa de um arquivo de 1 GB em 25 segundos, enquanto terei que esperar mais 5 minutos enquanto sync
libera isso para dirigir (estou exagerando, mas você entendeu).
É assim que monitoro rsync
o progresso em um loop para cada unidade:
PROGRESS="$(echo "$(du -s "/MEDIA/TARGET" 2>/dev/null | cut -f 1) / $(du -s "/MEDIA/SOURCE" 2>/dev/null | cut -f 1) " | bc -l)"
$PROGRESS
é um valor flutuante entre 0 e 1, indicando a proporção entre o uso da unidade de origem e o uso da unidade de destino.
Como posso modificar isso para considerar apenas os dados que já estão sincronizados com a unidade, e não apenas aguardando no cache do sistema?
Editar:
Descobri que dd
posso realizar gravações omitindo o cache do sistema. Fiz um teste e, de fato, copiar um arquivo dessa maneira reporta du
valores reais e minhas indicações de progresso finalmente seriam precisas:
dd if=/media/SOURCE/file of=/media/TARGET/file bs=4M oflag=direct
Isso usa o cache de leitura, mas desativa o cache de gravação, facilitando o rastreamento do processo, sem realizar leituras excessivas. O problema é que, para usar dd
em vez de rsync
preciso recriar manualmente a estrutura de diretórios. Não preciso cuidar dos atributos do arquivo ou das datas de modificação.
Acho que poderia usar uma combinação de find
e mkdir
primeiro dd
recriar a árvore de diretórios e depois copiar os arquivos um por um. Eu me pergunto - se há alguma desvantagem nessa abordagem?
Responder1
Parece que a melhor maneira de lidar com isso é usarsaída direta de arquivo. Desta forma du
as leituras serão muito mais precisas.
Infelizmente só dd
permite isso, então precisamos solucionar dois problemas:
dd
não sabe o que fazer com diretóriosdd
só pode copiar um arquivo por vez
Primeiro vamos definir os diretórios de entrada e saída:
SOURCE="/media/source-dir"
TARGET="/media/target-dir"
Agora vamos cd
para o diretório de origem para find
relatar os diretórios relativos que podemos manipular facilmente:
cd "$SOURCE"
Duplique a árvore de diretórios de $SOURCE
para$TARGET
find . -type d -exec mkdir -p "$TARGET{}" \;
Arquivos duplicados $SOURCE
para $TARGET
omitir cache de gravação (mas utilizando cache de leitura!)
find . -type f -exec dd if={} of="$TARGET{}" bs=8M oflag=direct \;
Isso não preservará os tempos de modificação dos arquivos, propriedade e outros atributos - mas para mim está tudo bem.