Je crée un fichier de 1 To avec des données aléatoires avec dd if=/dev/urandom of=file bs=1M count=1000000
. Maintenant, je vérifie kill -SIGUSR1 <PID>
la progression et j'obtiens ce qui suit:
691581+0 Datensätze ein
691580+0 Datensätze aus
725174190080 Bytes (725 GB) kopiert, 86256,9 s, 8,4 MB/s
800950+1 Datensätze ein
800950+0 Datensätze aus
839856947200 Bytes (840 GB) kopiert, 99429,5 s, 8,4 MB/s
dd: warning: partial read (809620 bytes); suggest iflag=fullblock
803432+1 Datensätze ein
803431+1 Datensätze aus
842459273876 Bytes (842 GB) kopiert, 99791,3 s, 8,4 MB/s
Je ne peux pas interpréter l'avertissement. Ça dit quoi? Mon fichier est-il vraiment aléatoire après l'avertissement ou y a-t-il un problème? Que signifie +0 ou +1 800950+1 Datensätze ein
et 800950+0 Datensätze aus
signifie? Après l'avertissement, c'est +1. Est-ce un nombre erroné?
LC_ALL=C
devant la commande, commeLC_ALL=C dd if=...
Réponses:
Résumé:
dd
est un outil grincheux qui est difficile à utiliser correctement. Ne l'utilisez pas, malgré les nombreux tutoriels qui vous le disent.dd
a une ambiance «credo unix street» qui y est attachée - mais si vous comprenez vraiment ce que vous faites, vous saurez que vous ne devriez pas le toucher avec un poteau de 10 pieds.dd
effectue un seul appel à l'read
appel système par bloc (défini par la valeur debs
). Il n'y a aucune garantie que l'read
appel système renvoie autant de données que la taille de mémoire tampon spécifiée. Cela a tendance à fonctionner pour les fichiers normaux et les périphériques de bloc, mais pas pour les canaux et certains périphériques de caractères. Voir Quand dd convient-il pour copier des données? (ou, quand sont read () et write () partial) pour plus d'informations. Si l'read
appel système renvoie moins d'un bloc complet,dd
transfère alors un bloc partiel. Il copie toujours le nombre spécifié de blocs, de sorte que le nombre total d'octets transférés est inférieur à celui demandé.L'avertissement concernant une «lecture partielle» vous dit exactement ceci: l'une des lectures était partielle, donc
dd
transféré un bloc incomplet. Dans le nombre de blocs,+1
signifie qu'un bloc a été lu partiellement; puisque le nombre de sorties est+0
, tous les blocs ont été écrits comme lus.Cela n'affecte pas le caractère aléatoire des données: tous les octets qui sont
dd
écrits sont des octets de lecture/dev/urandom
. Mais vous avez obtenu moins d'octets que prévu.Linux
/dev/urandom
accepte des requêtes arbitraires de grande taille (source:extract_entropy_user
indrivers/char/random.c
), ildd
est donc normalement sûr lors de la lecture. Cependant, la lecture de grandes quantités de données prend du temps. Si le processus reçoit un signal, l'read
appel système revient avant de remplir son tampon de sortie. Il s'agit d'un comportement normal et les applications sont censées appelerread
en boucle;dd
ne le fait pas, pour des raisons historiques (dd
les origines de sombres, mais il semble avoir commencé comme un outil pour accéder aux bandes, qui ont des exigences particulières, et n'a jamais été adapté pour être un outil à usage général). Lorsque vous vérifiez la progression, cela envoie audd
processus un signal qui interrompt la lecture. Vous avez le choix entre savoir combien d'octetsdd
copiera au total (assurez-vous de ne pas l'interrompre - pas de vérification de progression, pas de suspension), ou sachez combien d'octetsdd
ont été copiés jusqu'à présent, auquel cas vous ne pouvez pas savoir combien d'octets de plus il copiera.La version de
dd
dans GNU coreutils (comme on le trouve sur Linux non embarqué et sur Cygwin) a un drapeaufullblock
qui indiquedd
d'appelerread
en boucle (et idem pourwrite
) et donc de toujours transférer des blocs entiers. Le message d'erreur suggère que vous l'utilisiez; vous devez toujours l'utiliser (à la fois dans les drapeaux d'entrée et de sortie), sauf dans des circonstances très spéciales (principalement lors de l'accès aux bandes) - si vous l'utilisezdd
, c'est-à-dire: il existe généralement de meilleures solutions (voir ci-dessous).Une autre façon possible d'être sûr de ce qui
dd
va faire est de passer une taille de bloc de 1. Ensuite, vous pouvez dire combien d'octets ont été copiés à partir du nombre de blocs, mais je ne sais pas ce qui se passera si aread
est interrompu avant de lire le premier octet (ce qui n'est pas très probable dans la pratique mais peut se produire). Cependant, même si cela fonctionne, c'est très lent.Le conseil général sur l'utilisation
dd
est de ne pas utiliserdd
. Bien qu'ildd
soit souvent annoncé comme une commande de bas niveau pour accéder aux appareils, ce n'est en fait rien de tel: toute la magie se produit dans la partie du fichier de l'appareil (la/dev/…
) partie,dd
est juste un outil ordinaire avec un potentiel élevé d'utilisation abusive entraînant une perte de données . Dans la plupart des cas, il existe un moyen plus simple et plus sûr de faire ce que vous voulez, au moins sous Linux.Par exemple, pour lire un certain nombre d'octets au début d'un fichier, il suffit d'appeler
head
:J'ai fait un point de repère rapide sur ma machine et n'ai observé aucune différence de performance entre
dd
avec une grande taille de bloc ethead
.Si vous devez ignorer certains octets au début, dirigez-le
tail
vershead
:Si vous voulez voir la progression, appelez
lsof
pour voir le décalage du fichier. Cela ne fonctionne que sur un fichier standard (le fichier de sortie de votre exemple), pas sur un périphérique de caractères.Vous pouvez appeler
pv
pour obtenir un rapport d'avancement (meilleur quedd
le sien), au détriment d'un élément supplémentaire dans le pipeline (en termes de performances, il est à peine perceptible).la source
dd
commande que je ne savais pas que je devais connaître. Merci.dd
peut être utilisé en toute sécurité, grâce à sonfullblock
option. Mais si vous avez des coreutils GNU, vous n'avez pas besoin dedd
beaucoup. Les «dérivés» tels qu'ils ne ledcfldd
sont pasdd
, ils ne souffrent pas de ses défauts de conception, donc ma réponse ne s'applique pas à eux. Une très grande majorité de personnes qui l'utilisentdd
n'ont pas pris suffisamment de temps pour le comprendre (tout au plus, elles ont pris le temps de penser qu'elles le comprennent) et la façon dont elles l'utilisent entraîne une perte de données.L'avertissement se produit lorsqu'il
dd
n'a pas pu obtenir suffisamment de données pour remplir un bloc en une seule lecture. Cela se produit avec des sources de données erratiques ou lentes, ou des sources qui écrivent des données dans des unités plus petites que la taille de bloc demandée.Il n'y a aucun problème avec l'intégrité des données, mais le problème est que
dd
la lecture partielle est toujours considérée comme un bloc de lecture.Si vous n'utilisez pas l'
count
option, l'avertissement n'a pas d'importance, c'est juste une considération de performance. Mais aveccount
, vous n'obtiendrez pas la quantité de données que vous avez demandée. En raison de lectures partielles,of
sera plus petit qu'àcount*bs
la fin.Donc, lorsque vous utilisez
count
, techniquement, vous devriez toujours l'utiliseriflag=fullblock
également.Le
+x
devrait être le nombre de blocs partiels.la source
^ Ça va marcher. La désinformation que nous avions autrement ici est manifestement fausse.
dd
Les tampons sont explicites et donc, pour tamponner les entrées pour compter les occurrences, vous devez les tamponner explicitement. C'est tout. N'achetez pas le fud.la source