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. -
tee
bifurca 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=
.