З специфікації :
- Якщо
bs=
expr
операнд вказаний і немає перетворень, крім sync
, noerror
або notrunc
запитуються, дані, повернені з кожного вхідного блоку, записуються як окремий вихідний блок; якщо read()
повернення менше повного блоку і sync
перетворення не вказано, отриманий вихідний блок повинен бути того ж розміру, що і блок введення.
Отож, це, мабуть, викликає вашу плутанину. Та тому, що dd
це призначене для блокування, за замовчуванням часткових read()
сек буде відображатися 1: 1 частковим write()
с, або sync
d на хвіст відступ NUL або космічних символи в bs=
розмір , коли conv=sync
вказано.
Це означає , що dd
це безпечно використовувати для копіювання даних (ж / без ризику корупції з - за часткове читання або запис) , в кожному разі , крім одного , в якому вона довільно обмежена по count=
аргументу, оскільки в іншому випадку dd
буде щасливо write()
його вихід в однаковому розмірі блоків до тих, у яких його вклад був, read()
поки він read()
повністю не пройшов через нього. І навіть це застереження тільки справедливо , якщо bs=
вказано або obs=
в НЕ вказано, як таку пропозицію в специфікації говориться:
- Якщо
bs=
expr
операнд не вказаний, або перетворення, крім sync
, noerror
або notrunc
запитується, вхід обробляється і збирається в повнорозмірні вихідні блоки до досягнення кінця введення.
Без ibs=
і / або obs=
аргументи , це не може мати значення - тому що ibs
і obs
обидва той же розмір за замовчуванням. Однак ви можете отримати явну інформацію про буферизацію введення, вказавши різні розміри для або не вказавши bs=
(тому що це має перевагу) .
Наприклад, якщо ви робите:
IN| dd ibs=1| OUT
... тоді POSIX dd
буде write()
в шматки 512 байтів, збираючи кожен read()
байт окремо в один вихідний блок.
Інакше, якщо ви зробите ...
IN| dd obs=1kx1k| OUT
... POSIX одночасноdd
матиме read()
максимум 512 байт, але write()
кожен вихідний блок розміром мегабайт (ядро, що дозволяє і виключає, можливо, останній - тому що це EOF) повністю, збираючи вхід у повнорозмірні вихідні блоки .
Також із специфікації, однак:
count=n
- Скопіюйте лише n вхідних блоків.
count=
карти на i?bs=
блоки, і так, щоб обробляти довільне обмеження на count=
портативному порталі, вам знадобиться два dd
с. Найпрактичніший спосіб зробити це за допомогою двох dd
s - це передати висновок одного на вхід іншого, що, безумовно, ставить нас у сферу читання / запису спеціального файлу незалежно від вихідного типу введення.
IPC-труба означає, що, задаючи [io]bs=
аргументи, які, щоб зробити це безпечно, повинні зберігати такі значення в межах визначеного системою PIPE_BUF
межі. POSIX стверджує, що ядро системи повинно гарантувати лише атомні read()
s і write()
s в межах PIPE_BUF
, визначених у limits.h
. POSIX гарантує , що PIPE_BUF
буде принаймні ...
{_POSIX_PIPE_BUF}
- Максимальна кількість байтів, які гарантовано є атомними при записі на трубу.
- Значення: 512
... (що також буває за замовчуванням dd
розмір вводу-виводу за замовчуванням ) , але фактичне значення зазвичай становить принаймні 4k. У сучасній системі Linux це за замовчуванням 64k.
Отже, коли ви налаштовуєте свої dd
процеси, ви повинні робити це на факторі блоку на основі трьох значень:
- bs = (obs =
PIPE_BUF
або менший)
- n = загальна бажана кількість прочитаних байтів
- count = n / bs
Подібно до:
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
Вам потрібно синхронізувати dd
введення / обмін / обробку вхідних даних, які не можна шукати. Іншими словами, зробіть буферні труби явними, і вони перестануть бути проблемою. Ось для чого dd
. Невідома кількість тут - yes
розмір буфера, але якщо ви заблокуєте його до відомої кількості іншим, dd
то незначне помноження може зробити dd
безпечним для копіювання даних (без ризику пошкодження через часткове читання або запис) навіть коли довільно обмежує вхідний w / count=
w / будь-який довільний тип введення в будь-якій системі POSIX і не пропускає жодного байта.
Ось фрагмент із специфікації POSIX :
ibs=
expr
- Вкажіть розмір блоку введення в байтах за (за замовчуванням 512) .
expr
obs=
expr
- Вкажіть розмір вихідного блоку в байтах за (за замовчуванням 512) .
expr
bs=
expr
- Встановіть як розмір блоку вводу, так і виводу на
expr
байти, заміщення ibs=
та obs=
. Якщо перетворення, окрім sync
, noerror
та notrunc
не вказане, кожен вхідний блок повинен бути скопійований на вихід у вигляді одного блоку без агрегації коротких блоків.
Ви також знайдете тут щось краще пояснене тут .