Ich erstelle eine 1TB Datei mit zufälligen Daten mit dd if=/dev/urandom of=file bs=1M count=1000000
. Jetzt überprüfe ich kill -SIGUSR1 <PID>
den Fortschritt und erhalte folgendes:
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
Ich kann die Warnung nicht interpretieren. Was sagt es? Ist meine Datei nach der Warnung wirklich zufällig oder liegt ein Problem vor? Was bedeutet +0 oder +1 in 800950+1 Datensätze ein
und 800950+0 Datensätze aus
? Nach der Warnung ist es +1. Ist es eine Fehlerzahl?
LC_ALL=C
vor dem BefehlLC_ALL=C dd if=...
Antworten:
Zusammenfassung:
dd
ist ein verschrobenes Werkzeug, das schwer richtig zu bedienen ist. Verwenden Sie es trotz der zahlreichen Tutorials nicht.dd
ist mit einem „Unix Street Cred“ -Vibe verbunden - aber wenn Sie wirklich verstehen, was Sie tun, werden Sie wissen, dass Sie es nicht mit einer 10-Fuß-Stange anfassen sollten.dd
Ruft denread
Systemaufruf einmal pro Block auf (definiert durch den Wert vonbs
). Es kann nicht garantiert werden, dass derread
Systemaufruf so viele Daten zurückgibt wie die angegebene Puffergröße. Dies funktioniert in der Regel für reguläre Dateien und Blockgeräte, nicht jedoch für Pipes und einige Zeichengeräte. Siehe Wann eignet sich dd zum Kopieren von Daten? (oder, wenn für weitere Informationen read () und write () partial sind) . Wenn derread
Systemaufruf weniger als einen vollständigen Block zurückgibt, wirddd
ein Teilblock übertragen. Die angegebene Anzahl von Blöcken wird weiterhin kopiert, sodass die Gesamtanzahl der übertragenen Bytes geringer ist als angefordert.Die Warnung vor einem „teilweisen Lesevorgang“ sagt genau dies aus: Einer der Lesevorgänge war teilweise, sodass
dd
ein unvollständiger Block übertragen wurde. In den Blockzählungen+1
bedeutet dies, dass ein Block teilweise gelesen wurde; Da die Ausgabezählung gleich ist+0
, wurden alle Blöcke als gelesen ausgeschrieben.Dies hat keinen Einfluss auf die Zufälligkeit der Daten: Alle Bytes,
dd
aus denen geschrieben wird, sind Bytes, aus denen gelesen wird/dev/urandom
. Aber Sie haben weniger Bytes als erwartet.Linux unterstützt
/dev/urandom
beliebig große Anforderungen (source:extract_entropy_user
indrivers/char/random.c
) unddd
ist daher normalerweise sicher, wenn Sie davon lesen. Das Lesen großer Datenmengen erfordert jedoch Zeit. Wenn der Prozess ein Signal empfängt,read
kehrt der Systemaufruf zurück, bevor der Ausgabepuffer gefüllt wird. Dies ist normal und Anwendungen solltenread
in einer Schleife aufgerufen werden .dd
tut dies aus historischen Gründen nicht (seinedd
Ursprünge sind trübe, aber es scheint als Werkzeug für den Zugriff auf Bänder begonnen zu haben, die besondere Anforderungen haben und niemals als Allzweckwerkzeug angepasst wurden). Wenn Sie den Fortschritt überprüfen, sendet dies demdd
Prozess ein Signal, das den Lesevorgang unterbricht. Sie haben die Wahl, wie viele Bytes Sie wissen möchtendd
kopiert insgesamt (stellen Sie sicher, dass Sie es nicht unterbrechen - keine Fortschrittskontrolle, keine Unterbrechung), oder Sie wissen, wie viele Bytesdd
bis jetzt kopiert wurden. In diesem Fall können Sie nicht wissen, wie viele Bytes kopiert werden.Die Version von
dd
in GNU coreutils (wie sie unter nicht eingebettetem Linux und unter Cygwin zu finden ist) hat ein Flag,fullblock
das angibtdd
,read
in einer Schleife aufzurufen (und dito fürwrite
) und somit immer volle Blöcke zu übertragen. Die Fehlermeldung schlägt vor, dass Sie es verwenden; Sie sollten es immer verwenden (sowohl in Eingabe- als auch in Ausgabe-Flags), außer unter ganz besonderen Umständen (meistens beim Zugriff auf Bänder). Wenndd
überhaupt, gibt es normalerweise bessere Lösungen (siehe unten).Eine andere Möglichkeit, um sicherzugehen, was getan
dd
wird, besteht darin, eine Blockgröße von 1 zu übergeben. Dann können Sie feststellen, wie viele Bytes aus der Blockanzahl kopiert wurden, obwohl ich nicht sicher bin, was passieren wird, wenn aread
vor dem ersten Lesen unterbrochen wird Byte (was in der Praxis nicht sehr wahrscheinlich ist, aber passieren kann). Dies ist jedoch sehr langsam, auch wenn es funktioniert.Der allgemeine Rat zur Verwendung
dd
ist nicht zu verwendendd
. Obwohldd
oft als Befehl auf niedriger Ebene für den Zugriff auf Geräte geworben wird, ist dies in der Tat nicht der Fall: Alles, was in der Gerätedatei geschieht/dev/…
,dd
ist nur ein gewöhnliches Tool mit einem hohen Missbrauchspotenzial, das zu Datenverlust führt . In den meisten Fällen gibt es eine einfachere und sicherere Möglichkeit, das zu tun, was Sie möchten, zumindest unter Linux.Um beispielsweise eine bestimmte Anzahl von Bytes am Anfang einer Datei zu lesen, rufen Sie einfach Folgendes auf
head
:Ich habe auf meiner Maschine einen schnellen Benchmark durchgeführt und keinen Leistungsunterschied zwischen
dd
mit einer großen Blockgröße und festgestellthead
.Wenn Sie am Anfang einige Bytes überspringen müssen, leiten Sie
tail
inhead
:Wenn Sie den Fortschritt sehen möchten, rufen Sie
lsof
auf, um den Dateiversatz anzuzeigen. Dies funktioniert nur für eine reguläre Datei (die Ausgabedatei in Ihrem Beispiel), nicht für ein Zeichengerät.Sie können anrufen
pv
, um einen Fortschrittsbericht (besser alsdd
) auf Kosten eines zusätzlichen Elements in der Pipeline zu erhalten (in Bezug auf die Leistung kaum wahrnehmbar).quelle
dd
Befehl, von denen ich nicht wusste, dass ich sie wissen musste. Vielen Dank.dd
kann dank seinerfullblock
Option sicher verwendet werden . Aber wenn Sie GNU-Coreutils haben, brauchen Sie nichtdd
viel. „Derivate“, wiedcfldd
sind nichtdd
, sie nicht von ihren Konstruktionsfehler leiden, so meine Antwort auf sie nicht anwendbar ist . Eine große, große Mehrheit der Benutzerdd
hat sich nicht genügend Zeit genommen, um es zu verstehen (höchstens haben sie sich die Zeit genommen, um zu glauben , dass sie es verstehen), und die Art und Weise, wie sie es verwenden, führt zu Datenverlust.Die Warnung tritt auf, wenn
dd
nicht genügend Daten abgerufen werden konnten, um einen Block in einem Lesevorgang zu füllen. Dies geschieht bei fehlerhaften oder langsamen Datenquellen oder bei Quellen, die Daten in kleineren Einheiten als der von Ihnen angeforderten Blockgröße schreiben.Es gibt kein Problem mit der Datenintegrität, aber das Problem ist, dass
dd
ein teilweiser Lesevorgang immer noch als Leseblock gezählt wird.Wenn Sie die
count
Option nicht verwenden , spielt die Warnung kaum eine Rolle, sondern ist nur ein Leistungsaspekt. Mit erhaltencount
Sie jedoch nicht die von Ihnen angeforderte Datenmenge. Aufgrund teilweiser Lesevorgängeof
wird kleiner alscount*bs
am Ende.Also, wenn Sie verwenden
count
, sollten Sie technisch immer auch verwendeniflag=fullblock
.Das
+x
sollte die Anzahl der Teilblöcke sein.quelle
^ Das wird einfach funktionieren. Die Fehlinformationen, die hier sonst vorlagen, sind offensichtlich falsch.
dd
Die Puffer von sind explizit. Um Eingaben zu puffern, um Vorkommen zu zählen , müssen Sie explizit puffern. Das ist alles. Kaufen Sie nicht die Fud.quelle