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 den read
Systemaufruf einmal pro Block auf (definiert durch den Wert von bs
). Es kann nicht garantiert werden, dass der read
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 der read
Systemaufruf weniger als einen vollständigen Block zurückgibt, wird dd
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
in drivers/char/random.c
) und dd
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 sollten read
in einer Schleife aufgerufen werden . dd
tut dies aus historischen Gründen nicht (seine dd
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 dem dd
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 Bytes dd
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 angibt dd
, read
in einer Schleife aufzurufen (und dito für write
) 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). Wenn dd
überhaupt, gibt es normalerweise bessere Lösungen (siehe unten).
dd if=/dev/urandom iflag=fullblock oflag=fullblock of=file bs=1M count=1000000
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 a read
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
. Obwohl dd
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
:
head -c 1000000m </dev/urandom >file
Ich habe auf meiner Maschine einen schnellen Benchmark durchgeführt und keinen Leistungsunterschied zwischen dd
mit einer großen Blockgröße und festgestellt head
.
Wenn Sie am Anfang einige Bytes überspringen müssen, leiten Sie tail
in head
:
dd if=input of=output count=C bs=B seek=S
<input tail -c +$((S*B+1)) | head -c $((C*B)) >output
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.
lsof -a -p 1234 -d 1
cat /proc/1234/fdinfo/1
Sie können anrufen pv
, um einen Fortschrittsbericht (besser als dd
) auf Kosten eines zusätzlichen Elements in der Pipeline zu erhalten (in Bezug auf die Leistung kaum wahrnehmbar).