Eu não sei porque você precisa dessa engenhoca; talvez para fins de aprendizagem. OK, aqui está uma engenhoca mais complexa:
#!/bin/bash
block_size=1048576 # must be a plain number, without any suffix
count=0
while true
do
retbytes='dd if=./file.txt bs=$block_size skip=$count count=1 status=none |
tee >(dd of=other.txt bs=$block_size seek=$count status=none) |
wc -c'
[ "$retbytes" -eq "$block_size" ] || break
count=$((count + 1))
done
Seu script original usa sh e [[ . Isso não funciona. Na minha versão [ é suficiente onde eu preciso ( sh entenderia isso), mas eu preciso de bash de qualquer maneira por causa da sintaxe >(…) em outro lugar.
Você pode não ter notado, mas seu script processa todo o file.txt na primeira passagem porque você não disse a dd para parar após o primeiro bloco. (Observe que dd faz isso em partes , ou seja, a única primeira dd que você executa faz o que você deseja que todo o script faça). Posteriormente no loop, dd -s consecutivos sobrescrevem novamente cada vez menos (porque saltam mais e mais); toda vez até o final de file.txt embora. Eles funcionam é completamente inútil (a menos que o arquivo de entrada mude enquanto isso). Eu acho que sua intenção era o que o count=1 faz.
É assim que meu script funciona:
- Ele usa
dd-s separados para leitura e gravação. -
teebifurca a saída da leituradd. Uma cópia vai para a escritadd. - Os mesmos dados chegam a
wc -c, essa ferramenta informa o número de bytes que obteve. - O loop é encerrado se esse número não corresponder ao nosso tamanho de bloco.
Observação $block_size deve estar em um formato que permita a comparação com a saída de wc . Portanto, deve ser um número simples sem qualquer sufixo, apesar da capacidade de dd de entender alguns suficientes na opção bs= .