Aus der Spezifikation :
- Wenn der
bs=exprOperand angegeben ist und keine Konvertierungen ausgenommen sync, noerroroder notruncangefordert 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 syncKonvertierung 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 ddist ausgelegt für die Sperrung, die standardmäßig Teil read()s wird abgebildet 1: 1 zu Teil- write()s, oder auch syncauf Schwanz Polsterung NUL oder Raum Zeichen auf d out bs=Größe , wenn conv=syncangegeben 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 dddie 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=exprOperand nicht angegeben, oder eine Umwandlung außer sync, noerroroder notruncbeantragt 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 ibsund obsbeide 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 ddwird 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 ddwird 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 dds. Der praktischste Weg, dies mit zwei dds 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_BUFGrenzwerts halten müssen. POSIX besagt, dass der Systemkern nur Atome read()und write()Atome innerhalb der PIPE_BUFin definierten Grenzen garantieren darf limits.h. POSIX garantiert, PIPE_BUFdass mindestens ...
{_POSIX_PIPE_BUF}
- Maximale Anzahl von Bytes, die beim Schreiben in eine Pipe garantiert atomar sind.
- Wert: 512
... (was auch die Standard- ddE / 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 ddProzesse einrichten, sollten Sie einen Blockfaktor verwenden , der auf drei Werten basiert:
- bs = (obs =
PIPE_BUFoder 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 ddist es da. Die unbekannte Größe ist hier yesdie Puffergröße - aber wenn Sie diese mit einer anderen auf eine bekannte Größe beschränken, ddkann 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
exprBytes ein und ersetzen Sie ibs=und obs=. Wenn keine andere Konvertierung als sync, noerrorund notruncangegeben 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 .