Короткий зміст: ddце химерний інструмент, який важко правильно використовувати. Не використовуйте його, незважаючи на численні підручники, які вам так говорять. ddдо нього прикріплена вібрація «unix street Credit» - але якщо ви справді зрозумієте, що ви робите, ви знатимете, що не слід торкатися її 10-футовим полюсом.
ddробить один виклик до readсистемного виклику на блок (визначається значенням bs). Немає гарантії, що readсистемний виклик повертає стільки даних, скільки вказаний розмір буфера. Це, як правило, працює для звичайних файлів і блокових пристроїв, але не для труб та деяких пристроїв символів. Дивіться, коли dd підходить для копіювання даних? (або, коли читаються () та записуються () частково) для отримання додаткової інформації. Якщо readсистемний виклик повертає менше одного повного блоку, то ddпередає частковий блок. Він все ще копіює вказану кількість блоків, тому загальна кількість переведених байтів менша, ніж потрібно.
Попередження про "часткове зчитування" говорить саме про це: одне з прочитаних було частковим, тому ddпередано неповний блок. У підрахунку блоків +1означає, що один блок був прочитаний частково; Оскільки підрахунок виходу є +0, всі блоки записувались як прочитані.
Це не впливає на випадковість даних: усі байти, які ddвиписують, - це байти, з яких вони читаються /dev/urandom. Але у вас менше байтів, ніж очікувалося.
Linux /dev/urandomвміщує довільні великі запити (джерело: extract_entropy_userв drivers/char/random.c), тому ddзазвичай безпечно при читанні з нього. Однак для читання великої кількості даних потрібен час. Якщо процес отримує сигнал, readсистемний виклик повертається перед заповненням його вихідного буфера. Це нормальна поведінка, і програми повинні викликати readцикл; ddцього не роблять з історичних причин ( ddджерела похмурі, але, здається, він почав бути інструментом доступу до стрічок, які мають особливі вимоги, і ніколи не був адаптований як інструмент загального призначення). Коли ви перевіряєте хід, це надсилає ddпроцесу сигнал, який перериває прочитане. У вас є вибір між знанням, скільки байтівddбуде скопійовано загалом (переконайтеся, що не переривати її - не перевірка ходу, не призупинення) або знаючи, скільки байтів ddскопійовано до цього часу, і в цьому випадку ви не можете знати, скільки ще байтів буде скопійовано.
У версії ddGNU coreutils (як це знайдено в невбудованому Linux та Cygwin) є прапор, fullblockякий говорить ddпро дзвінок readу циклі (та ditto для write) та таким чином завжди передає повні блоки. Повідомлення про помилку говорить про те, що ви використовуєте його; ви завжди повинні використовувати його (як у вхідних, так і у вихідних прапорах), за винятком дуже особливих обставин (переважно під час доступу до стрічок) - якщо ви ddвзагалі використовуєте , тобто: зазвичай є кращі рішення (див. нижче).
dd if=/dev/urandom iflag=fullblock oflag=fullblock of=file bs=1M count=1000000
Ще один можливий спосіб бути впевненим у тому dd, що робити, - це передати розмір блоку 1. Тоді ви можете сказати, скільки байтів було скопійовано з підрахунку блоків, хоча я не впевнений, що буде, якщо readперерватиметься перед читанням першого байт (що на практиці мало ймовірно, але може статися). Однак навіть якщо це працює, це дуже повільно.
Загальну пораду щодо використання dd- не використовуватиdd . Хоча ddце часто рекламується як команда низького рівня для доступу до пристроїв, насправді такого немає: вся магія відбувається у файлі пристрою ( /dev/…) частини - ddце просто звичайний інструмент з високим потенціалом для неправильного використання, що призводить до втрати даних . У більшості випадків існує простіший і безпечніший спосіб зробити те, що ви хочете, принаймні в Linux.
Наприклад, щоб прочитати певну кількість байт на початку файлу, просто зателефонуйте head:
head -c 1000000m </dev/urandom >file
Я зробив швидкий орієнтир на своїй машині і не помітив різниці в продуктивності між ddвеликим розміром блоку та head.
Якщо необхідно пропустити кілька байт на початку, труби tailв head:
dd if=input of=output count=C bs=B seek=S
<input tail -c +$((S*B+1)) | head -c $((C*B)) >output
Якщо ви хочете побачити прогрес, зателефонуйте, lsofщоб переглянути зсув файлу. Це працює лише у звичайному файлі (вихідний файл у вашому прикладі), а не на символьному пристрої.
lsof -a -p 1234 -d 1
cat /proc/1234/fdinfo/1
Ви можете зателефонувати, pvщоб отримати звіт про хід (краще, ніж dd), за рахунок додаткового пункту в конвеєрі (з точки зору продуктивності, це ледь помітно).