Ze specyfikacji :
- Jeżeli
bs=
expr
argument jest określony i nie są wymagane żadne konwersje inne niż sync
, noerror
lub dane notrunc
są wymagane, dane zwrócone z każdego bloku wejściowego zapisuje się jako osobny blok wyjściowy; jeżeli read()
zwraca mniej niż pełny blok, a sync
konwersja nie jest określona, wynikowy blok wyjściowy ma taki sam rozmiar jak blok wejściowy.
Prawdopodobnie to właśnie powoduje twoje zamieszanie. Tak, ponieważ dd
jest przeznaczony do blokowania, domyślnie częściowe read()
s zostaną zamapowane 1: 1 na częściowe write()
, lub sync
d na wypełnieniu ogona NUL lub znakami spacji do bs=
rozmiaru, gdy conv=sync
zostanie określony.
Oznacza to, że dd
można bezpiecznie używać do kopiowania danych (bez ryzyka uszkodzenia z powodu częściowego odczytu lub zapisu) w każdym przypadku, z wyjątkiem jednego, w którym jest on arbitralnie ograniczony przez count=
argument, ponieważ w przeciwnym razie jego dane wyjściowe w blokach o identycznych rozmiarach dd
będą szczęśliwie write()
do tych, w których jego wkład był, read()
dopóki nie read()
przejdzie przez to całkowicie. I nawet to zastrzeżenie jest prawdziwe tylko wtedy, gdy bs=
jest określone lub nieobs=
jest określone, ponieważ następne zdanie w specyfikacji stwierdza:
- Jeżeli
bs=
expr
argument nie jest określony lub wymagana jest konwersja inna niż sync
, noerror
lub notrunc
wymagane jest, dane wejściowe będą przetwarzane i gromadzone w pełnowymiarowych blokach wyjściowych, aż do osiągnięcia końca danych wejściowych.
Bez argumentów ibs=
i / lub obs=
nie ma to znaczenia - ponieważ ibs
i obs
oba mają domyślnie ten sam rozmiar. Możesz jednak uzyskać wyraźne informacje na temat buforowania danych wejściowych, określając dla nich różne rozmiary i nie określając bs=
(ponieważ ma to pierwszeństwo) .
Na przykład, jeśli wykonasz:
IN| dd ibs=1| OUT
... wtedy POSIX dd
będzie write()
składał się z 512 bajtów, zbierając każdy pojedynczy read()
bajt w pojedynczy blok wyjściowy.
W przeciwnym razie, jeśli zrobisz ...
IN| dd obs=1kx1k| OUT
... POSIX dd
będzie miał jednocześnie read()
maksymalnie 512 bajtów, ale write()
każdy blok wyjściowy wielkości megabajta (jądro pozwala i może z wyjątkiem ostatniego - ponieważ to jest EOF) w całości, zbierając dane wejściowe do pełnowymiarowych bloków wyjściowych .
Jednak również ze specyfikacji:
count=n
- Kopiuj tylko n bloków wejściowych.
count=
mapuje na i?bs=
bloki, więc aby poradzić sobie z dowolnym ograniczeniem count=
przenośnym, potrzebujesz dwóch dd
s. Najbardziej praktycznym sposobem na zrobienie tego za pomocą dwóch dd
s jest podłączenie wyjścia jednego z nich do wejścia drugiego, co z pewnością stawia nas w sferze czytania / pisania specjalnego pliku, niezależnie od pierwotnego typu wejścia.
Rura IPC oznacza, że przy określaniu [io]bs=
argumentów, że aby to zrobić bezpiecznie, musisz utrzymać takie wartości w ramach zdefiniowanego PIPE_BUF
limitu systemu. POSIX stwierdza, że jądro systemu musi zagwarantować tylko atomowe read()
S i write()
S w granicach PIPE_BUF
, jak określono w limits.h
. Gwarancje POSIX, które PIPE_BUF
będą co najmniej ...
{_POSIX_PIPE_BUF}
- Maksymalna liczba bajtów, która jest gwarantowana jako niepodzielna podczas zapisywania na potoku.
- Wartość: 512
... (który również jest domyślnym dd
rozmiarem bloku we / wy) , ale rzeczywista wartość wynosi zwykle co najmniej 4k. W aktualnym systemie Linux jest to domyślnie 64k.
Więc kiedy konfigurujesz swoje dd
procesy, powinieneś to zrobić na podstawie współczynnika blokowego opartego na trzech wartościach:
- bs = (obs =
PIPE_BUF
lub mniej)
- n = całkowita pożądana liczba odczytanych bajtów
- count = n / bs
Lubić:
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
Musisz zsynchronizować i / ow /, dd
aby obsłużyć niewidoczne dane wejściowe. Innymi słowy, wyraź bufory potoku i przestań być problemem. Po to dd
jest. Nieznana ilość tutaj jest yes
wielkości bufora - ale jeśli zablokujesz ją na znanej ilości z inną, dd
to małe, świadome zwielokrotnienie może dd
bezpiecznie wykorzystać do kopiowania danych (bez ryzyka uszkodzenia z powodu częściowego odczytu lub zapisu) nawet gdy arbitralnie ograniczasz wejście w / count=
w / dowolny typ wejścia w dowolnym systemie POSIX i bez utraty jednego bajtu.
Oto fragment specyfikacji POSIX :
ibs=
expr
- Określ rozmiar bloku wejściowego, w bajtach, do (domyślnie 512) .
expr
obs=
expr
- Określ rozmiar bloku wyjściowego, w bajtach, do (domyślnie 512) .
expr
bs=
expr
- Ustaw rozmiar bloku wejściowego i wyjściowego na
expr
bajty, zastępując ibs=
i obs=
. Jeśli konwersja nie inna niż sync
, noerror
i notrunc
jest określona, każdy blok wejściowy zostanie skopiowany na wyjście jako pojedynczy blok bez agregacji krótkie bloki.
Znajdziesz tu także niektóre to lepiej wyjaśnione tutaj .