J'ai une archive tar d'une seule image disque. L'image à l'intérieur de ce fichier tar fait environ 4 Go. Je dirige la sortie de tar xf
dans dd
pour écrire l'image disque sur une carte SD. Le vidage de disque ne s'arrête jamais tant que la carte n'est pas pleine. Voici ma session shell:
$ ls -l disk.img.tgz
-rw-r--r-- 1 confus confus 192M Okt 5 00:53
$ tar -tvf disk.img.tgz
-rw-r--r-- root/root 4294968320 2018-10-05 00:52 disk.img
$ lsblk -lb /dev/sdc
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdc 8:32 1 16022241280 0 disk
$ tar zxf disk.img.tgz -O | sudo dd status=progress conv=sync bs=1M of=/dev/sdc
[sudo] password for user:
15992881152 bytes (16 GB, 15 GiB) copied, 212 s, 75,4 MB/s
dd: error writing '/dev/sdc': No space left on device
0+15281 records in
15280+0 records out
16022241280 bytes (16 GB, 15 GiB) copied, 217,67 s, 73,6 MB/s
Pourquoi? Il devrait s'arrêter une fois que le hit a écrit l'image de 4 Go dans le panier de 16 Go et ne jamais manquer d'espace!
pipe
tar
dd
disk-image
embrouiller
la source
la source
dd
et de l'écrire dans un autre fichier?tar zxf disk.img.tgz -O | dd status=progress conv=sync bs=1M of=/path/to/some/file/on/disk
? Si oui, cela vous donne-t-il une copie exacte du fichier d'origine?conv=sync
? Vouliez-vous utiliserconv=fsync
peut-être?Réponses:
C'est parce que tu le fais mal.
Vous utilisez,
bs=1M
mais la lecture depuis stdin, pipe, aura des lectures plus petites. En fait, selon dd, vous n'avez pas obtenu une seule lecture complète.Et puis vous avez
conv=sync
qui complète les lectures incomplètes avec des zéros.dd
a reçu 0 lectures complètes et 15281 lectures incomplètes et a écrit 15280 blocs complets (conv = sync zéro rempli). Ainsi, la sortie est beaucoup plus grande que l'entrée, jusqu'à ce que vous n'ayez plus d'espace.Pour résoudre ce problème, vous pouvez supprimer
conv=sync
et ajouteriflag=fullblock
.Pour illustrer, considérons
yes
, qui par défaut crache une infinie "y \ ny \ ny \ n".Avec
dd bs=1M conv=sync
cela ressemble à ceci:Il obtient donc un bloc incomplet de "y \ ny \ ny \ n" (0x00000 - 0x1e000, 122880 octets) puis écrit le 1M restant sous forme de zéros (0x01e000 - 0x100000, 925696 octets). Dans la plupart des cas, vous ne voulez pas que cela se produise. Le résultat est aléatoire de toute façon, car vous n'avez aucun contrôle réel sur le caractère incomplet de chaque lecture. Comme ici, la deuxième lecture n'est plus 122880 octets mais 73728 octets.
dd conv=sync
est rarement utile et même dans les cas où cela serait le bienvenu, comme écrire des zéros lorsque vous obtenez des erreurs de lecture, les choses iront horriblement mal.la source
dd
commande sousstrace
(en supposant que Linux) aurait montré que chaque lecture courte du canal était suivie d'une écriture complète de 1 Mo.dd
commande est fondamentalement rompue et inutilisable. Il est spécifié de fonctionner dans desread
s et deswrite
s individuels , mais ces opérations sont spécifiées de telle sorte qu'elles peuvent toujours produire de courtes lectures ou écritures, et ce n'est pas une erreur. Par conséquent, le comportement dedd
dépend d'un comportement non spécifié.dd
, mais cela m'a amené à apprendre quelque chose de vous. Ce dont je ne suis toujours pas complètement sûr, c'est de savoir si et quand celadd
aurait pris fin. Je suppose que oui, mais comme il écrivait en fait 1 partie de données réelles et 9 parties de zéros, il se serait arrêté après avoir écrit environ 40G. Est-ce exact?