Ich habe ein Tar-Archiv eines einzelnen Disk-Image. Das Bild in dieser Teer-Datei ist ungefähr 4 GB groß. Ich leite die Ausgabe von tar xf
in dd
um das Disk-Image auf eine SD-Karte zu schreiben. Der Speicherauszug stoppt nie, bis die Karte voll ist. Hier ist meine Shell-Sitzung:
$ ls -l disk.img.tgz
-rw-r--r-- 1 confus confus 192M Okt 5 00:53
$ tar -tvf disk.img.tgz
-rw-r--r-- root/root 4294968320 2018-10-05 00:52 disk.img
$ lsblk -lb /dev/sdc
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdc 8:32 1 16022241280 0 disk
$ tar zxf disk.img.tgz -O | sudo dd status=progress conv=sync bs=1M of=/dev/sdc
[sudo] password for user:
15992881152 bytes (16 GB, 15 GiB) copied, 212 s, 75,4 MB/s
dd: error writing '/dev/sdc': No space left on device
0+15281 records in
15280+0 records out
16022241280 bytes (16 GB, 15 GiB) copied, 217,67 s, 73,6 MB/s
Warum? Es sollte aufhören, nachdem ein Treffer das 4 GB-Image auf den 16 GB-Wagen geschrieben hat, und es sollte nie der Platz ausgehen!
pipe
tar
dd
disk-image
verwechseln
quelle
quelle
dd
und in eine andere Datei zu schreiben?tar zxf disk.img.tgz -O | dd status=progress conv=sync bs=1M of=/path/to/some/file/on/disk
? Wenn ja, erhalten Sie dann eine genaue Kopie der Originaldatei?conv=sync
? Meinten Sieconv=fsync
vielleicht verwenden?Antworten:
Es ist, weil du es falsch machst.
Sie verwenden,
bs=1M
aber das Lesen von stdin, pipe, führt zu kleineren Lesungen. Tatsächlich haben Sie laut dd keinen vollständigen Lesevorgang erhalten.Und dann haben Sie
conv=sync
welche Ergänzungen unvollständig mit Nullen gelesen.dd
Erhielt 0 vollständige und 15281 unvollständige Lesevorgänge und schrieb 15280 vollständige Blöcke (conv = Sync zero filled). Die Ausgabe ist also viel größer als die Eingabe, bis Sie keinen Platz mehr haben.Um dies zu lösen, können Sie entfernen
conv=sync
und hinzufügeniflag=fullblock
.Betrachten Sie zur Veranschaulichung,
yes
welche standardmäßig unendlich "y \ ny \ ny \ n" ausspuckt.Damit
dd bs=1M conv=sync
sieht es so aus:Daher wird ein unvollständiger Block mit "y \ ny \ ny \ n" (0x00000 - 0x1e000, 122880 Bytes) abgerufen, und die verbleibenden 1 MB werden als Nullen (0x01e000 - 0x100000, 925696 Bytes) geschrieben. In den meisten Fällen möchten Sie dies nicht. Das Ergebnis ist ohnehin zufällig, da Sie keine wirkliche Kontrolle darüber haben, wie unvollständig die einzelnen Lesevorgänge werden. Wie hier ist der zweite Lesevorgang nicht länger 122880 Bytes, sondern 73728 Bytes.
dd conv=sync
ist selten nützlich und selbst in Fällen, in denen es erwünscht wäre, Nullen zu schreiben, wenn Lesefehler auftreten, wird dies furchtbar schief gehen.quelle
dd
Befehls unterstrace
(Linux vorausgesetzt) gezeigt, dass auf jeden kurzen Lesevorgang von der Pipe ein vollständiger 1-MB-Schreibvorgang folgte.dd
Befehl grundsätzlich fehlerhaft und unbrauchbar ist. Es ist angegeben, in einzelnenread
s undwrite
s zu arbeiten, aber diese Operationen sind so angegeben, dass sie immer kurze Lese- oder Schreibvorgänge erzeugen können, und es ist kein Fehler. Infolgedessendd
hängt das Verhalten von von nicht spezifiziertem Verhalten ab.dd
, aber es führte mich dazu, etwas von dir zu lernen. Was ich mir noch nicht ganz sicher bin ist, ob und wanndd
ich gekündigt hätte. Ich gehe davon aus, dass dies der Fall wäre, aber da tatsächlich 1 Teil tatsächliche Daten und 9 Teil Nullen geschrieben wurden, hätte es nach dem Schreiben von etwa 40 G aufgehört. Ist das korrekt?