Ich wollte eine 1-GB-Zufallsdatei erstellen und habe den folgenden Befehl verwendet.
dd if=/dev/urandom of=output bs=1G count=1
Stattdessen erhalte ich jedes Mal, wenn ich diesen Befehl starte, eine 32-MB-Datei:
<11:58:40>$ dd if=/dev/urandom of=output bs=1G count=1
0+1 records in
0+1 records out
33554431 bytes (34 MB, 32 MiB) copied, 0,288321 s, 116 MB/s
Was ist falsch?
BEARBEITEN:
Dank großartiger Antworten in diesem Thema kam ich mit einer Lösung, die 32 Chunks mit einer Größe von 32 MB liest und 1 GB ergibt:
dd if=/dev/urandom of=output bs=32M count=32
Es wurde eine andere Lösung angegeben, die 1 GB direkt in den Speicher liest und dann auf die Festplatte schreibt. Diese Lösung benötigt viel Speicher und wird daher nicht bevorzugt:
dd if=/dev/urandom of=output bs=1G count=1 iflag=fullblock
script
dd
random-number-generator
Trismegistos
quelle
quelle
dd
. Ich würde verwendenhead
,cat
oderrsync
an seiner Stelle fast immer. Und Ihre Frage, ob einer der Gründe, warum die Alternativen in der Regel sicherer sind.head
kann diese Aufgabe nicht ohne die-c
Option ausführen , die nicht in POSIX enthalten ist . Ich kenne keine Version,cat
die das lösen kann.rsync
ist ein völlig anderes Dienstprogramm. Das ist weder hier noch dort; Beim Durchblättern der Manpage sehe ich auch keine Möglichkeit, dieses Problem zu lösen./dev/urandom
ist es auch nicht in POSIX ...Antworten:
bs
Die Puffergröße bezeichnet die Größe eines einzelnen read () - Aufrufs von dd.(Beide
bs=1M count=1
undbs=1k count=1k
führen beispielsweise zu einer 1-MiB-Datei, die erste Version erledigt dies jedoch in einem Schritt, die zweite in 1024 kleinen Blöcken.)Normale Dateien können mit nahezu jeder Puffergröße gelesen werden (solange dieser Puffer in den Arbeitsspeicher passt), aber Geräte und "virtuelle" Dateien arbeiten häufig sehr nahe an den einzelnen Aufrufen und unterliegen einer willkürlichen Einschränkung der Datenmenge, die sie pro Aufruf erzeugen read () Aufruf.
Für
/dev/urandom
ist dieses Limit in urandom_read () in drivers / char / random.c definiert :Dies bedeutet, dass bei jedem Aufruf der Funktion die angeforderte Größe auf 33554431 Byte begrenzt wird.
Im Gegensatz zu den meisten anderen Tools wird dd standardmäßig keine Neuversuche durchführen, nachdem weniger Daten als angefordert empfangen wurden - Sie erhalten die 32 MiB und das wars. (Damit es automatisch wiederholt wird, müssen Sie wie in Kamils Antwort angeben
iflag=fullblock
.)Beachten Sie auch, dass "die Größe eines einzelnen read ()" bedeutet, dass der gesamte Puffer auf einmal in den Speicher passen muss, sodass massive Blockgrößen auch einer massiven Speichernutzung durch dd entsprechen .
Und es ist alles sinnlos, weil Sie normalerweise keine Leistung erzielen, wenn Sie über ~ 16–32 MiB-Blöcke hinausgehen - Syscalls sind hier nicht der langsame Teil, sondern der Zufallsgenerator.
Also der Einfachheit halber einfach benutzen
head -c 1G /dev/urandom > output
.quelle
iflag=fullblock
eine GNU-Erweiterung des POSIX-dd
Dienstprogramms ist . Da die Frage Linux nicht spezifiziert, sollte die Verwendung von Linux-spezifischen Erweiterungen wahrscheinlich explizit erwähnt werden, damit zukünftige Leser, die versuchen, ein ähnliches Problem auf einem Nicht-Linux-System zu lösen, nicht verwirrt werden.dd
auf meiner Maschine durchgeführt, mit Blockgrößen von 1k bis 512M. Mit einer Intel 750 SSD wurde eine optimale Leistung (ca. 1300 MB / s) bei 2 MB-Blöcken erzielt, die in etwa Ihren Ergebnissen entspricht. Größere Blöcke haben weder geholfen noch gehindert. Die/dev/zero
optimale Leistung (fast 20 GB / s) lag bei 64 KB- und 128 KB-Blöcken. Sowohl kleinere als auch größere Blöcke verringerten die Leistung und entsprachen in etwa meinem vorherigen Kommentar. Fazit: Benchmark für Ihre aktuelle Situation. Und natürlich hat keiner von uns ein Benchmarking durchgeführt/dev/random
: Pdd
schneller zu sein. Eine kurze Zusammenfassung zeigte, dasshead
8-KB-Lesevorgänge und zwei 4-KB-Schreibvorgänge verwendet werden, was interessant ist (GNU coreutils 8.26 unter Debian 9.6 / Linux 4.8).head
Geschwindigkeiten liegen in der Tat irgendwo zwischendd bs=4k
unddd bs=8k
.head
Geschwindigkeiten sinken um ~ 40% gegenüberdd if=/dev/zero bs=64k
und um ~ 25% gegenüberdd if=/dev/nvme0n1 bs=2M
. Die Lesevorgänge/dev/zero
sind natürlich stärker CPU-begrenzt, aber für die SSD-E / A spielt auch die Warteschlange eine Rolle. Es ist ein größerer Unterschied als ich erwartet hatte.dd
kann kleiner sein alsibs
(Anmerkung:bs
gibt beidesibs
und anobs
), soferniflag=fullblock
nicht anders angegeben.0+1 records in
zeigt an, dass0
vollständige und1
teilweise Blöcke gelesen wurden. Jeder vollständige oder teilweise Block erhöht jedoch den Zähler.Ich kenne nicht den genauen Mechanismus, der dasBearbeiten: Diese gleichzeitige Antwort erklärt den Mechanismus, mit demdd
Lesen eines Blocks bewirkt, der kleiner ist als1G
in diesem speziellen Fall. Ich vermute, ein Block wird vor dem Schreiben in den Speicher gelesen, sodass die Speicherverwaltung möglicherweise stört (dies ist jedoch nur eine Vermutung).dd
ein Block gelesen wird, der kleiner ist als1G
in diesem speziellen Fall.Jedenfalls empfehle ich nicht so groß
bs
. Ich würde verwendenbs=1M count=1024
. Das Wichtigste ist: Ohneiflag=fullblock
einen Leseversuch kann weniger als gelesen werdenibs
(es sei dennibs=1
, ich denke, dies ist recht ineffizient).Wenn Sie also eine genaue Datenmenge lesen müssen, verwenden Sie
iflag=fullblock
. Hinweisiflag
wird von POSIX nicht benötigt,dd
möglicherweise wird dies nicht unterstützt. Nach dieser Antwortibs=1
ist wahrscheinlich die einzige POSIX-Methode, um eine genaue Anzahl von Bytes zu lesen. Wenn Sie sich ändern, müssenibs
Sie das natürlich neu berechnencount
. In Ihrem Fall wird das Problem wahrscheinlich auch ohne eine Senkungibs
auf32M
oder weniger behobeniflag=fullblock
.In meinem Kubuntu würde ich deinen Befehl so korrigieren:
quelle