Dalle specifiche :
- Se
bs=
expr
viene specificato l' operando e nessuna conversione diversa da sync
, noerror
o notrunc
richiesta, i dati restituiti da ciascun blocco di input devono essere scritti come blocchi di output separati; se il valore read()
restituito è inferiore a un blocco completo e la sync
conversione non è specificata, il blocco di output risultante deve avere le stesse dimensioni del blocco di input.
Quindi questo è probabilmente ciò che causa la tua confusione. Sì, poiché dd
è progettato per il blocco, per impostazione predefinita i read()
s parziali verranno mappati da 1: 1 a write()
s parziali , oppure verranno rimpiazzati sync
sul pad di coda NUL o i caratteri spaziali alla bs=
dimensione quando conv=sync
viene specificato.
Ciò significa che dd
è sicuro da usare per la copia dei dati (senza rischio di corruzione a causa di una lettura o scrittura parziale) in ogni caso tranne uno in cui è arbitrariamente limitato da un count=
argomento, perché altrimenti dd
sarà felicemente il write()
suo output in blocchi di dimensioni identiche a quelli in cui il suo input era read()
fino a quando non read()
è completamente attraverso di esso. E anche questo avvertimento è vero solo quando bs=
è specificato o nonobs=
è specificato, come afferma la frase successiva nelle specifiche:
- Se l'
bs=
expr
operando non è specificato o una conversione diversa da sync
, noerror
o notrunc
è richiesta, l'input deve essere elaborato e raccolto in blocchi di output full-size fino al raggiungimento della fine dell'ingresso.
Senza ibs=
e / o obs=
argomenti questo non può importare, perché ibs
e obs
hanno entrambi la stessa dimensione di default. Tuttavia, è possibile ottenere espliciti sul buffer di input specificando dimensioni diverse per entrambi e non specificando bs=
(poiché ha la precedenza) .
Ad esempio, se lo fai:
IN| dd ibs=1| OUT
... quindi un POSIX dd
verrà write()
suddiviso in blocchi di 512 byte raccogliendo ogni singolo read()
byte in un singolo blocco di output.
Altrimenti, se lo fai ...
IN| dd obs=1kx1k| OUT
... un POSIX dd
avrà un read()
massimo di 512 byte alla volta, ma write()
ogni blocco di output di dimensioni megabyte (kernel che consente ed esclude possibilmente l'ultimo - perché quello è EOF) per intero raccogliendo l'input in blocchi di output full-size .
Anche dalle specifiche, però:
count=n
- Copia solo n blocchi di input.
count=
esegue la mappatura su i?bs=
blocchi, quindi per gestire un limite arbitrario su count=
portabile avrai bisogno di due dd
secondi. Il modo più pratico per farlo con due dd
s è convogliare l'output di uno nell'input di un altro, il che sicuramente ci mette nel regno della lettura / scrittura di un file speciale indipendentemente dal tipo di input originale.
Una pipe IPC significa che quando si specifica [io]bs=
sostiene che, per farlo in modo sicuro, è necessario mantenere tali valori entro il PIPE_BUF
limite definito dal sistema . POSIX afferma che il kernel del sistema deve garantire solo atomiche read()
s e write()
s nei limiti delle PIPE_BUF
quali definite limits.h
. POSIX garantisce che PIPE_BUF
avere un almeno ...
{_POSIX_PIPE_BUF}
- Numero massimo di byte che è garantito essere atomico quando si scrive su una pipe.
- Valore: 512
... (che è anche il dd
blocco predefinito di I / O predefinito ) , ma il valore effettivo è di solito almeno 4k. Su un sistema Linux aggiornato è, per impostazione predefinita, 64k.
Quindi, quando configuri i tuoi dd
processi, dovresti farlo su un fattore di blocco basato su tre valori:
- bs = (obs =
PIPE_BUF
o inferiore)
- n = numero totale desiderato di byte letti
- conteggio = n / bs
Piace:
yes | dd obs=1k | dd bs=1k count=10k of=/dev/null
10240+0 records in
10240+0 records out
10485760 bytes (10 MB) copied, 0.1143 s, 91.7 MB/s
Devi sincronizzare i / ow / dd
per gestire input non ricercabili. In altre parole, rendere espliciti i buffer di pipe e cessano di essere un problema. Questo è ciò che dd
serve. La quantità sconosciuta qui è yes
la dimensione del buffer - ma se la blocchi a una quantità nota con un'altra, dd
una moltiplicazione informata può rendere dd
sicuro l'uso per la copia dei dati (senza rischio di corruzione a causa di una lettura o scrittura parziale) anche quando si limita arbitrariamente l'ingresso w / count=
w / qualsiasi tipo di ingresso arbitrario su qualsiasi sistema POSIX e senza perdere un singolo byte.
Ecco uno snippet dalle specifiche POSIX :
ibs=
expr
- Specificare la dimensione del blocco di input, in byte, per (il valore predefinito è 512) .
expr
obs=
expr
- Specificare la dimensione del blocco di output, in byte, per (il valore predefinito è 512) .
expr
bs=
expr
- Impostare le dimensioni dei blocchi di input e output su
expr
byte, sostituendo ibs=
e obs=
. Se nessuna conversione diversa da sync
, noerror
ed notrunc
è specificata, ciascun blocco di ingresso deve essere copiato nell'uscita come blocco singolo senza aggregare blocchi corti.
Troverai anche alcuni di questi spiegati meglio qui .