De la spec :
- Si l'
bs=
expr
opérande est spécifié et qu'aucune conversion autre que sync
, noerror
ou notrunc
n'est demandée, les données renvoyées par chaque bloc d'entrée doivent être écrites comme un bloc de sortie séparé. si le nombre read()
retourné est inférieur à un bloc complet et que la sync
conversion n'est pas spécifiée, le bloc de sortie résultant aura la même taille que le bloc d'entrée.
Donc, c'est probablement ce qui cause votre confusion. Oui, car il dd
est conçu pour le blocage, les read()
s partiels sont par défaut mappés de 1: 1 à write()
s partiels , ou bien sync
d out sur le remplissage de queue NUL ou les caractères d'espace à la bs=
taille conv=sync
spécifiée.
Cela signifie que dd
est sûr à utiliser pour la copie des données (w / aucun risque de corruption en raison d'une lecture partielle ou écriture) dans tous les cas , mais celui dans lequel il est arbitrairement limité par un count=
argument parce que sinon se dd
fera un plaisir de write()
sa sortie en blocs de taille identique à ceux dans lesquels son entrée a été read()
jusqu’à ce qu’elle soit read()
complètement passée à travers elle. Et même cette mise en garde est que vrai quand bs=
est spécifié ou obs=
est non spécifié, comme la phrase suivante dans les états spécifications:
- Si l'
bs=
expr
opérande n'est pas spécifié, ou si une conversion autre que sync
, noerror
ou notrunc
est demandée, l'entrée doit être traitée et collectée dans des blocs de sortie de taille normale jusqu'à la fin de l'entrée.
Sans ibs=
et / ou obs=
arguments, cela n'a pas d'importance - ibs
et obs
ont la même taille par défaut. Cependant, vous pouvez expliquer explicitement la mise en mémoire tampon des entrées en spécifiant des tailles différentes pour l'une ou l'autre et non pour la spécification bs=
(car elle est prioritaire) .
Par exemple, si vous le faites:
IN| dd ibs=1| OUT
... alors un POSIX dd
sera write()
composé de 512 octets en regroupant chaque read()
octet unique dans un seul bloc de sortie.
Sinon, si vous le faites ...
IN| dd obs=1kx1k| OUT
... un Posix dd
sera read()
au maximum de 512 octets à la fois, mais write()
chaque méga - octet de taille bloc de sortie (noyau permettant et sauf peut - être la dernière - parce que ce EOF) dans son intégralité par la collecte d' entrée en blocs de sortie pleine grandeur .
Aussi de la spécification, cependant:
count=n
- Copier uniquement n blocs d'entrée.
count=
mappe à des i?bs=
blocs, et donc afin de gérer une limite arbitraire sur count=
portable, vous aurez besoin de deux dd
s. La manière la plus pratique de le faire avec deux dd
s est de canaliser la sortie de l'un vers l'entrée de l'autre, ce qui nous place sûrement dans le domaine de la lecture / écriture d'un fichier spécial, quel que soit le type d'entrée d'origine.
Un canal IPC signifie que lorsque vous spécifiez des [io]bs=
arguments, vous devez conserver ces valeurs dans les PIPE_BUF
limites définies par le système, de manière sécurisée . POSIX indique que le noyau système ne doit garantir que les read()
s atomiques et les write()
s dans les limites PIPE_BUF
définies par limits.h
. POSIX garantit que ce PIPE_BUF
soit au moins ...
{_POSIX_PIPE_BUF}
- Nombre maximal d'octets dont l'atome est garanti lors de l'écriture dans un canal.
- Valeur: 512
... (qui se trouve être également la dd
taille de bloc par défaut d'e / s) , mais la valeur réelle est généralement d'au moins 4k. Sur un système Linux à jour, il est de 64k par défaut.
Ainsi, lorsque vous configurez vos dd
processus, vous devez le faire sur un facteur de blocage basé sur trois valeurs:
- bs = (obs =
PIPE_BUF
ou moins)
- n = nombre total d'octets lus souhaités
- compte = n / bs
Comme:
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
Vous devez synchroniser les dd
entrées / sorties / pour gérer les entrées non recherchées. En d'autres termes, explicitez les tampons de canaux et ces problèmes cessent. C'est pour ça dd
. La quantité inconnue ici est yes
la taille du tampon de - mais si vous bloquez cette quantité avec une autre quantité connue,dd
une multiplication un peu informée peut être dd
utilisée de manière sûre pour la copie de données (sans risque de corruption dû à une lecture ou une écriture partielle). même lorsque vous limitez arbitrairement l'entrée avec count=
n'importe quel type d'entrée sur n'importe quel système POSIX et sans manquer un seul octet.
Voici un extrait de la spécification POSIX :
ibs=
expr
- Spécifiez la taille du bloc d'entrée, en octets, par (512 par défaut) .
expr
obs=
expr
- Spécifiez la taille du bloc de sortie, en octets, par (512 par défaut) .
expr
bs=
expr
- Définissez les tailles de bloc d'entrée et de sortie sur
expr
octets, remplaçants ibs=
et obs=
. Si aucune conversion autre que sync
, noerror
et notrunc
n'est spécifiée, chaque bloc d'entrée doit être copié dans la sortie sous la forme d'un bloc unique sans agréger les blocs courts.
Vous trouverez également une partie de ceci expliqué mieux ici .