Argument 'seek' im Befehl dd


20

Können mir einige erklären, was in den folgenden Zeilen passiert?

dd if=/dev/urandom bs=4096 seek=7 count=2 of=file_with_holes

Besonders suchen Teil ist nicht klar

Manpages sagt:

 seek=BLOCKS
              skip BLOCKS obs-sized blocks at start of output

Was ist ein Obs-Block?

Antworten:


22

dddient zum Kopieren von Datenblöcken aus einer Eingabedatei in eine Ausgabedatei. Die ddOptionen für die Blockgröße lauten auf der Manpage wie folgt :

ibs=expr
    Specify the input block size, in bytes, by expr (default is 512).
obs=expr
    Specify the output block size, in bytes, by expr (default is 512).
bs=expr
    Set both input and output block sizes to expr bytes, superseding ibs= and obs=.

Die dd seekOption ähnelt dem UNIX lseek()-Systemaufruf 1 . Es bewegt den Lese- / Schreibzeiger innerhalb der Datei. Von der Manpage :

seek=n
    Skip n blocks (using the specified output block size) from the beginning of the output file before copying. 

Normale Dateien in UNIX haben die praktische Eigenschaft, dass Sie sie nicht von Anfang an lesen oder schreiben müssen. Sie können von dort aus überall suchen und lesen oder schreiben. Dies bs=4096 seek=7bedeutet, dass Sie vom Anfang der Ausgabedatei an eine Position von 7 * 4096 Byte verschieben und von dort aus mit dem Schreiben beginnen müssen. Es wird nicht in den Teil der Datei geschrieben, der zwischen 0 und 7 * 4096 Byte liegt.

Bereiche gewöhnlicher Dateien, in die niemals geschrieben wird, werden nicht einmal vom zugrunde liegenden Dateisystem zugewiesen. Diese Bereiche werden genannt Löcher und die Dateien als Sparse-Dateien bezeichnet . In Ihrem Beispiel file_with_holeswird am Anfang ein Loch von 7 * 4096 Byte angezeigt. (h / t @frostschutz für den Hinweis, dass dddie Ausgabedatei standardmäßig abgeschnitten wird.)

Es ist in Ordnung, diese nicht zugewiesenen Bereiche zu lesen. Sie erhalten eine Reihe von Nullen.

[1] Damals, als ddgeschrieben wurde, war der analoge Systemaufruf seek().


Interessanterweise ist meine Manpage in dieser Hinsicht ärgerlich unauffällig - `bs = BYTES liest und schreibt bis zu BYTES Bytes auf einmal`
Graeme

Ich habe "seek" unter UNIX nicht gesehen. Vielleicht "lseek", denke ich.
Kangear

1
Nur zur Erinnerung, ich habe versucht, ein Laufwerk zu suchen (Beispiel:) dd if=/dev/zero bs=512 count=2 seek=8388607998 of=/dev/sdd, aber diese 'Dateien' / Deskriptoren sind nicht suchbar:dd: /dev/sdd: cannot seek: Invalid argument 0+0 records in 0+0 records out 0 bytes copied, 0.00765396 s, 0.0 kB/s
Pysis

1
@Pysis Disk-Geräte können normalerweise gesucht werden, aber bei sehr großen Geräten kann es zu Problemen kommen. Wie groß (in Bytes) ist Ihr / dev / sdd?
Mark Plotnick

1
Vielleicht habe ich vorher und kann mich nicht erinnern. Ich versuche, auf den GPT-Sicherungssektor oder 2 am Ende einer 4-TB-Festplatte zuzugreifen.
Pysis

6

Die anderen Antworten haben es bereits erklärt, aber wenn Sie irgendwelche Zweifel haben, können Sie sehen, was damit ddgeschieht strace.

$ strace dd if=/dev/urandom bs=4096 seek=7 count=2 of=file_with_holes
# output is shortened considerably
open("/dev/urandom", O_RDONLY)          = 0
open("file_with_holes", O_RDWR|O_CREAT, 0666) = 1
ftruncate(1, 28672)                     = 0
lseek(1, 28672, SEEK_CUR)               = 28672
read(0, "\244\212\222v\25\342\346\226\237\211\23\252\303\360\201\346@\351\6c.HF$Umt\362;E\233\261"..., 4096) = 4096
write(1, "\244\212\222v\25\342\346\226\237\211\23\252\303\360\201\346@\351\6c.HF$Umt\362;E\233\261"..., 4096) = 4096
read(0, "~\212q\224\256\241\277\344V\204\204h\312\25pw9\34\270WM\267\274~\236\313|{\v\6i\22"..., 4096) = 4096
write(1, "~\212q\224\256\241\277\344V\204\204h\312\25pw9\34\270WM\267\274~\236\313|{\v\6i\22"..., 4096) = 4096
close(0)                                = 0
close(1)                                = 0
write(2, "2+0 records in\n2+0 records out\n", 312+0 records in
2+0 records out
) = 31
write(2, "8192 bytes (8.2 kB) copied", 268192 bytes (8.2 kB) copied) = 26
write(2, ", 0.00104527 s, 7.8 MB/s\n", 25, 0.00104527 s, 7.8 MB/s
) = 25
+++ exited with 0 +++

Es öffnet sich /dev/urandomzum Lesen ( if=/dev/urandom), öffnet sich file_with_holeszum Erstellen / Schreiben ( of=file_with_holes).

Dann wird file_with_holesauf 4096*7= 28672bytes ( bs=4096 seek=7) gekürzt . Das Abschneiden bedeutet, dass der Dateiinhalt nach dieser Position verloren geht. (Hinzufügen conv=notrunc, um diesen Schritt zu vermeiden). Dann sucht es nach 28672Bytes.

Dann liest es 4096Bytes ( bs=4096verwendet als ibs) aus /dev/urandom, schreibt 4096Bytes ( bs=4096verwendet als obs) infile_with_holes , gefolgt von einem weiteren Lesen und Schreiben ( count=2).

Dann schließt /dev/urandom, schließt file_with_holesund druckt es, dass es 2*4096= 8192Bytes kopiert . Schließlich wird es ohne Fehler (0) beendet.


5

obsist die Ausgabeblockgröße und ibsist die Eingabeblockgröße. Wenn Sie bsohne ibsoder angeben, wird obsdies für beide verwendet.

Ihre Suche wird also zu Beginn Ihrer Ausgabe aus 7 Blöcken mit 4096 oder 28672 Bytes bestehen. Dann kopieren Sie 2 Blöcke von 4096 oder 8192 Bytes vom Beginn der Eingabe bis zu diesem Punkt in der Ausgabe.


1

Suche wird nur die Ausgabedatei "aufblasen". Seek = 7 bedeutet, dass am Anfang der Ausgabedatei 7 "leere" Blöcke mit Ausgabeblockgröße = obs = 4096 Byte eingefügt werden. Auf diese Weise können sehr große Dateien schnell erstellt werden.


1
Oder um Daten zu Beginn zu überspringen, die Sie nicht ändern möchten. Leere Blöcke ergeben sich nur, wenn die Ausgabedatei anfangs nicht so viele Daten enthielt. Das Handbuch ist auch nicht klar, in welcher obsBeziehung bsder Befehl steht, bsder ersetzt, obswenn er nicht vorhanden ist.
Graeme
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.