wie man dd benutzt, um das Laufwerk mit Einsen zu füllen


7

Das Befüllen eines Laufwerks mit / dev / urandom scheint sehr langsam zu sein, daher habe ich eine mit FF gefüllte Datei erstellt:

dd if=/dev/zero ibs=1k count=1000 | tr "\000" "\377" >ff.bin

Ich möchte das Laufwerk mit Kopien dieser Datei füllen, aber der folgende Befehl schreibt nur einmal:

dd if=ff.bin of=/dev/sdb count=10000

Wie fülle ich das Laufwerk mit Kopien der Datei oder gibt es eine schnellere Möglichkeit, das Laufwerk mit Einsen zu füllen?


5
Warum nicht Nullen verwenden? 1-Bit löscht eine Festplatte nicht besser als 0-Bit.
Gilles 'SO - hör auf böse zu sein'

3
@ Gilles Ich denke, Null ist speziell genug, dass der Festplattentreiber betrügen und nichts wirklich auf die Festplatte schreiben könnte, sondern nur Blöcke als leer markiert. Ich denke, eine virtuelle Festplatte tut dies. Trotzdem hängt es davon ab, aus welchem ​​Grund er ein Laufwerk füllt. Wenn es Sicherheit ist, sind weder 0 noch 1 sicher genug, und auch das Füllen mit Zufall wäre nicht gut, wenn die Festplatte SSD ist
pqnet

2
@pqnet Zero ist nichts Besonderes für die physische Speicherung. Bei einer virtuellen Festplatte mag dies der Fall sein, aber das Befüllen mit irgendetwas ist unsicher. Bei SSD gibt es spezielle Probleme mit neu zugewiesenen Blöcken, aber das Schreiben mit Werten ungleich Null hilft dabei nicht.
Gilles 'SO - hör auf böse zu sein'

@ Gilles gut, der Grund, aus dem er auf seine Festplatte schreiben möchte, wird nicht erklärt, daher denke ich, dass es großartig wäre, wenn die Frage geklärt wird
pqnet

Der Ehrwürdige ddhat die Option seek=N skip N obs-sized blocks at start of output, sodass Sie eine Schleife schreiben können, um an der richtigen Stelle k*Mauf dem Ausgabeblockgerät zu suchen, bevor Sie das Schreiben der M-Datei wiederholen.
David Tonhofer

Antworten:


11

Einfach machen:

tr '\0' '\377' < /dev/zero > /dev/sdb

Es wird mit einem Fehler abgebrochen, wenn das Laufwerk voll ist.

Verwendung ddmacht hier keinen Sinn. Sie ddstellen sicher, dass Lese- und Schreibvorgänge eine bestimmte Größe haben. Hier gibt es keinen Grund, es zu tun. trwird Lese- / Schreibvorgänge von 4 oder 8 kiB ausführen, was gut genug sein sollte.


1
Sie könnten sogar einen Schub bekommen, tr ... | tee - - - > /dev/diskaber die Wahrscheinlichkeit, dass trallein der Schreibengpass nicht bereits erreicht und überschritten wird, ist ziemlich gering.
Mikeserv

1
@mikeserv, ich denke, die einzige Möglichkeit, die Leistung zu steigern, besteht darin, die Anzahl der Systemaufrufe zu reduzieren. teewird dafür nicht helfen. stdbuf -o1M tr...kann helfen.
Stéphane Chazelas

Einverstanden. Ich benutze es manchmal /dev/zeroals Eimer mit tr- wie für Zeilenumbrüche oder was auch immer - und es verbraucht immer eine ganze CPU. Ich denke, der Zug aus dem Kernel, der all diese Bytes herauspumpt, ist ziemlich schwer. Ich dachte, dass die Datei vielleicht einfach getäuscht werden könnte. Vielleicht war es dumm.
Mikeserv

4
Die Verwendung von @mikeserv tee - - -erhöht den Durchsatz in meinen Tests erheblich. Das geht von 800MiB / s für tr(950MiB / s mit stdbuf) bis 2,3GiB / s mit Tee, wie Sie auf jeden Fall weit über der Rate sagen, die ein aktuelles Laufwerk aushalten kann.
Stéphane Chazelas

Vielleicht stimmt das, aber diese 2,3 g Flut wird immer noch rieseln, sobald Ihre Pipeline außerhalb der Jobkontrolle liegt. stdbufist schlau - ich benutze es nie und sollte es wahrscheinlich. Und dies ist das zweite Mal in so vielen Tagen, dass mich jemand darauf aufmerksam gemacht hat. Ich denke, die andere Sache ist CentOS - ich habe irgendwo über einen 64-KB-Kernel-Puffer gelesen.
Mikeserv

4

Für eine schnellere /dev/urandomAlternative gibt es shred -v -n 1(wenn Pseudozufall in Ordnung ist) oder die Verwendung cryptsetupmit zufälligem Schlüssel und Nullstellen (für verschlüsselte Nullen). Auch ohne AES-Beschleunigung schlägt es leicht /dev/urandomGeschwindigkeiten.

Ich bin mir nicht sicher, wie schnell es trist, sonst könntest du es einfach dd if= | tr | dd of=.

Die Verwendung einer Datei als Musterquelle kann folgendermaßen erfolgen:

(while [ 1 ]; do cat file; done) | dd of=...

Obwohl die Datei ziemlich groß sein sollte, damit dies aus der Ferne effizient ist.

Wenn count=Ihnen das wichtig ist, fügen Sie iflag=fullblockes dem ddBefehl hinzu. Teillesevorgänge sind möglich, was dazu führen würde, dass Teilblöcke als vollständige Blöcke gezählt werden. Dies ist besonders dann der Fall bs=1M, wenn Sie größere Blockgrößen (wie ) verwenden, die Sie verwenden sollten, wenn Sie Geschwindigkeit wünschen.


Shred ist schnell und meldet Fortschritte! Vielen Dank!
Linuxfix

2

Dies ist eine sehr schnelle und effiziente Methode, um immer wieder 64-kB-Zeichenfolgen von 0xFF zu schreiben, wobei awk<8% der CPU verbraucht werden und nur durch die Geschwindigkeit des Laufwerks begrenzt wird, auf das Sie schreiben.

Ich habe versucht, trwie hier vorgeschlagen zu verwenden, und festgestellt, dass es schmerzhaft langsam ist und viel CPU verbraucht, um jedes einzelne Byte zu übersetzen. Meine Methode arbeitet in 64-kB-Blöcken und ist mindestens 3,5-mal schneller als die auf Einzelzeichen basierende tr(26 MB / s gegenüber 7 MB / s bei alten PATA-Hardware - in 52 Minuten in Stille gegenüber 3+ Stunden mit lauten Lüfterdrehzahlen ...). Ich mag es, wenn Leute grundlegende Informatikkenntnisse abwischen, ohne vorher ihre Meinung zu testen.

Ich empfehle, das folgende Skript mithilfe printfder Shell zu erstellen, anstatt zu versuchen, es einzuschreiben, vida die meisten Boot-CD-ROMs Ihnen nicht genügend tmp-Speicherplatz bieten, damit das Pufferprotokoll 65.536 Mal kopiert und eingefügt werden kann ...

1) Verfassen Sie das Skript

$ printf "echo | awk '{\n\twhile (1) {\n\t\tprintf(\"%%s\", \"" >/tmp/writeones.sh
$ for i in `seq 1 65536`; do printf '\377' >>/tmp/writeones.sh; done
$ printf "\");\n}\n}'\n" >>/tmp/writeones.sh

Das Ausgabeskript sieht folgendermaßen aus: (Lassen Sie einige Zeichen 0xff in der Zeichenfolge weg.)

echo | awk '{                                                                                                                           
    while (1) {
        printf("%s", "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ...");
    }
}'

2) Testen Sie das Skript:

$ sh /tmp/writeones.sh | od -Ax -tx1
000000 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
*
Ctrl+C

3) Führen Sie das Skript aus und leiten Sie es mit dd auf Ihr Laufwerk (überprüfen Sie, ob Sie das richtige Laufwerk haben !!!):

# sh /tmp/writeones.sh | dd of=/dev/ada0 bs=65536 &

Warum habe ich 64 kB gewählt? 1. Arg-Listenbeschränkung von AWK und 2. für meine Hardware erreicht dies die beste Geschwindigkeit für mich. Ich habe auch versucht, dies nur in einer Shell mit printf zu schreiben, und festgestellt, dass es 40% langsamer war und wegen aller Gabeln 80% der CPU verbrauchte.


Aber es gibt keine Gabeln?
David Tonhofer

0

Um die SSD-Geschwindigkeit zu testen, habe ich ein kleines Perl-Programm geschrieben, um "Nullen", "Einsen" oder alphanumerische Zeichen in ein Blockgerät in der Befehlszeile zu schreiben. Es ruft nicht den ddGolem auf, sondern führt nur direkte Schreib- und Synchronisierungsvorgänge durch. Kann hier hilfreich sein:

https://github.com/dtonhofer/wild_block_device_filler

Führen Sie es einfach als

wildly_fill_block_device.pl --dev=sdX1 --fillpat 1 --chunksize=1024P --sync

Und es schreibt 0xFFs in / dev / sdX1 (ungepuffert, unter Verwendung von Perls syswrite ()) in Blöcken von (in diesem Fall) "1024 physischen Blöcken", während die Daten nach jedem Schreibvorgang mit fdatasync () auf die Festplatte synchronisiert werden. Auf meiner SSD läuft dies mit ~ 70 MiB / s.

Sie werden gefragt, ob Sie SICHER sind, bevor die Partition oder die Festplatte zerstört wird.


0

Sie können dies in Bash ziemlich effizient ohne externe Dateien tun, außer mit dem Gerät, auf das geschrieben werden soll, oder mit externen Befehlen, außer dd.

  1. Verwenden Sie printfdiese Option , um ein Byte mit allen einzelnen Bits zu generieren und in eine Bash-Variable einzufügen.
  2. Verketten Sie die Bash-Variable mehrmals mit sich selbst.
  3. Verwenden Sie die Bash-Prozessersetzung, um eine unendlich lange Eingabedatei zu fälschen, echodie die Bash-Variable wiederholt ohne nachfolgende Zeilenumbruch enthält.
  4. Verwenden Sie das als Eingabedatei für dd.

Wenn Sie GNU haben dd, erhalten Sie einen schönen Fortschrittsbalken mit:

sudo -i
bash
ones="$( printf '\xff' )"; for _ in {1..16}; do ones="$ones$ones"; done; dd status=progress bs=65536 if=<( while true; do echo -n "$ones"; done ) of=/dev/whatever

Entfernen Sie das, status=progresswenn es bei Ihnen nicht funktioniert. Das 65536ist 2 16 , weil das Anfangsbyte mit allen einem Bit 16mal dupliziert wurde.


-1

So wischen Sie mit 1er:

while true; do echo 1 ; done | dd of=/dev/sdX status=progress

So testen Sie das Wischtuch:

dd if=/dev/sdX count=1 bs=512
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.