Como detectar o final do arquivo com o dd?

0

Eu criei um arquivo de teste de 10 MB:

dd if=/dev/zero of=file.txt count=1024 bs=10240

Em seguida, escrevi o script abaixo para copiar esse arquivo em partes. Mas parece que o dd não está detectando o EOF e sempre retorna 0, então o loop while continua para sempre.

#!/bin/sh

block_size=1048576
count=0
retval=0
while true
do
        dd if=./file.txt of=other.txt bs=${block_size} seek=${count} skip=${count} status=none
        retval=$?
        if [[ $retval -ne 0 ]]; then
                break
        fi
        count=$((count + 1))
done

Então, como posso obter o dd para retornar um código de diferença quando passa do EOF?

    
por hebbo 02.05.2018 / 23:03

1 resposta

3

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:

  1. Ele usa dd -s separados para leitura e gravação.
  2. tee bifurca a saída da leitura dd . Uma cópia vai para a escrita dd .
  3. Os mesmos dados chegam a wc -c , essa ferramenta informa o número de bytes que obteve.
  4. 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= .

    
por 03.05.2018 / 11:29