Aus der Spezifikation :
- Wenn der
bs=
expr
Operand angegeben ist und keine Konvertierungen ausgenommen sync
, noerror
oder notrunc
angefordert werden , die von jedem Eingangsblock zurückgegebenen Daten werden als separater Ausgangsblock geschrieben werden; Wenn der read()
Rückgabewert kleiner als ein vollständiger Block ist und die sync
Konvertierung nicht angegeben ist, muss der resultierende Ausgabeblock dieselbe Größe wie der Eingabeblock haben.
Das ist wahrscheinlich der Grund für Ihre Verwirrung. Ja, denn dd
ist ausgelegt für die Sperrung, die standardmäßig Teil read()
s wird abgebildet 1: 1 zu Teil- write()
s, oder auch sync
auf Schwanz Polsterung NUL oder Raum Zeichen auf d out bs=
Größe , wenn conv=sync
angegeben wird.
Dies bedeutet, dass die Verwendung zum Kopieren von Daten sicherdd
ist (ohne Verfälschungsrisiko aufgrund eines teilweisen Lese- oder Schreibvorgangs), jedoch in jedem Fall, in dem sie willkürlich durch ein count=
Argument begrenzt werden , da ansonsten dd
die write()
Ausgabe gerne in gleich großen Blöcken erfolgt zu denen, in denen seine Eingabe war, read()
bis es read()
vollständig durch es ist. Und selbst diese Einschränkung nur wahr , wenn bs=
angegeben wird , oder obs=
wird nicht angegeben, wie der nächste Satz in dem spec heißt es :
- Wenn der
bs=
expr
Operand nicht angegeben, oder eine Umwandlung außer sync
, noerror
oder notrunc
beantragt wird, muss der Eingang verarbeitet und wird in volle Größe Ausgabeblocks gesammelt , bis das Ende der Eingabe erreicht ist.
Ohne ibs=
und / oder obs=
Argument kann dies keine Rolle - da ibs
und obs
beide die gleiche Größe in der Standardeinstellung. Sie können sich jedoch explizit über die Eingabepufferung informieren, indem Sie entweder unterschiedliche Größen angeben oder keine angeben bs=
(da dies Vorrang hat) .
Zum Beispiel, wenn Sie:
IN| dd ibs=1| OUT
... dann ein POSIX dd
wird write()
in Blöcken von 512 Bytes , die durch das Sammeln jeden einzeln read()
Byte in einen einzigen Ausgangsblock.
Ansonsten, wenn Sie tun ...
IN| dd obs=1kx1k| OUT
... a POSIX dd
wird read()
bei maximal 512 Byte zu einer Zeit, aber write()
jeder Megabyte-sized Ausgabeblock (kernel ermöglicht und mit Ausnahme vielleicht die letzten - weil das EOF ist) vollständig durch Eingabe in dem Sammeln voller Größe Ausgangsblocks .
Aber auch aus der Spezifikation:
count=n
- Kopieren Sie nur n Eingabeblöcke.
count=
Ordnet i?bs=
Blöcke zu, und um eine willkürliche Beschränkung für count=
portabel zu handhaben, benötigen Sie zwei dd
s. Der praktischste Weg, dies mit zwei dd
s zu tun, besteht darin, die Ausgabe von einem in die Eingabe eines anderen zu leiten, was uns sicherlich in den Bereich des Lesens / Schreibens einer speziellen Datei versetzt, unabhängig vom ursprünglichen Eingabetyp.
Eine IPC-Pipe bedeutet, dass Sie bei der Angabe von [io]bs=
Argumenten, um dies sicher zu tun, diese Werte innerhalb des vom System festgelegten PIPE_BUF
Grenzwerts halten müssen. POSIX besagt, dass der Systemkern nur Atome read()
und write()
Atome innerhalb der PIPE_BUF
in definierten Grenzen garantieren darf limits.h
. POSIX garantiert, PIPE_BUF
dass mindestens ...
{_POSIX_PIPE_BUF}
- Maximale Anzahl von Bytes, die beim Schreiben in eine Pipe garantiert atomar sind.
- Wert: 512
... (was auch die Standard- dd
E / A-Blockgröße ist) , aber der tatsächliche Wert beträgt normalerweise mindestens 4 KB . Auf einem aktuellen Linux-System sind es standardmäßig 64 KB.
Wenn Sie also Ihre dd
Prozesse einrichten, sollten Sie einen Blockfaktor verwenden , der auf drei Werten basiert:
- bs = (obs =
PIPE_BUF
oder kleiner)
- n = gewünschte Gesamtzahl der gelesenen Bytes
- count = n / bs
Mögen:
yes | dd obs=1k | dd bs=1k count=10k of=/dev/null
10240+0 records in
10240+0 records out
10485760 bytes (10 MB) copied, 0.1143 s, 91.7 MB/s
Sie müssen i / ow / synchronisieren dd
, um nicht suchbare Eingaben zu verarbeiten. Mit anderen Worten, machen Sie Pipe-Puffer explizit und sie hören auf, ein Problem zu sein. Dafür dd
ist es da. Die unbekannte Größe ist hier yes
die Puffergröße - aber wenn Sie diese mit einer anderen auf eine bekannte Größe beschränken, dd
kann ein wenig informierte Multiplikation dd
sicheres Kopieren von Daten ermöglichen (ohne Verfälschungsrisiko aufgrund eines teilweisen Lese- oder Schreibvorgangs). Selbst wenn die Eingabe mit count=
einem beliebigen Eingabetyp auf einem beliebigen POSIX-System willkürlich eingeschränkt wird und kein einziges Byte fehlt.
Hier ist ein Ausschnitt aus der POSIX-Spezifikation :
ibs=
expr
- Geben Sie die Größe des Eingabeblocks in Byte an (Standard ist 512) .
expr
obs=
expr
- Geben Sie die Ausgabeblockgröße in Byte an (Standard ist 512) .
expr
bs=
expr
- Stellen Sie sowohl die Eingabe- als auch die Ausgabeblockgröße auf
expr
Bytes ein und ersetzen Sie ibs=
und obs=
. Wenn keine andere Konvertierung als sync
, noerror
und notrunc
angegeben ist, wird jeder Eingabeblock als einzelner Block in die Ausgabe kopiert, ohne kurze Blöcke zu aggregieren.
Einige Erklärungen dazu finden Sie auch hier .