аргумент 'seek' в команде dd

20

Могут ли некоторые объяснить мне, что происходит в следующих строках?

dd if=/dev/urandom bs=4096 seek=7 count=2 of=file_with_holes

особенно искать часть не ясно

Справочные страницы говорят:

 seek=BLOCKS
              skip BLOCKS obs-sized blocks at start of output

Что такое блок размером с OBS?

user2799508
источник

Ответы:

22

ddпредназначен для копирования блоков данных из входного файла в выходной файл. Параметры ddразмера блока приведены на странице руководства :

ibs=expr
    Specify the input block size, in bytes, by expr (default is 512).
obs=expr
    Specify the output block size, in bytes, by expr (default is 512).
bs=expr
    Set both input and output block sizes to expr bytes, superseding ibs= and obs=.

dd seekВариант похож на UNIX lseek()системный вызов 1 . Он перемещает указатель чтения / записи в файле. Со страницы руководства :

seek=n
    Skip n blocks (using the specified output block size) from the beginning of the output file before copying. 

Обычные файлы в UNIX имеют удобное свойство: вам не нужно читать или записывать их, начиная с самого начала; Вы можете искать где угодно и читать или писать, начиная с этого. Таким образом, bs=4096 seek=7означает перейти в позицию 7 * 4096 байт от начала выходного файла и начать запись оттуда. Он не будет записывать в часть файла размером от 0 до 7 * 4096 байт.

Области обычных файлов, которые вообще никогда не записываются, даже не выделяются базовой файловой системой. Эти области называются дырами, а файлы называются разреженными файлами . В вашем примере file_with_holesв начале будет отверстие размером 7 * 4096 байт. (h / t @frostschutz для указания, что усекает ddвыходной файл по умолчанию.)

Можно читать эти нераспределенные области; Вы получаете кучу нулей.

[1] назад, когда ddбыло написано, аналогичный системный вызов был seek().

Марк Плотник
источник
Интересно, что моя справочная страница раздражающе нежелательна на этом - `bs = BYTES читает и записывает до байтов байтов за раз`
Грэм,
Я не видел "seek" в UNIX, может быть, "lseek", наверное.
Кангеар
1
Просто чтобы заметить, я пытался найти устройство накопителя (exmaple:) dd if=/dev/zero bs=512 count=2 seek=8388607998 of=/dev/sdd, но эти «файлы» / дескрипторы недоступны для поиска:dd: /dev/sdd: cannot seek: Invalid argument 0+0 records in 0+0 records out 0 bytes copied, 0.00765396 s, 0.0 kB/s
Пизис
1
Дисковые устройства @Pysis обычно доступны для поиска, но, возможно, есть проблемы с очень большими устройствами. Насколько велик (в байтах) ваш / dev / sdd?
Марк Плотник,
1
Может быть, я раньше и не могу вспомнить. Я пытаюсь получить доступ к резервному сектору GPT или 2 в конце диска 4TB.
Пизис
6

Другие ответы уже объяснили это, но если у вас есть какие-либо сомнения, вы можете увидеть, что ddс этим делать strace.

$ strace dd if=/dev/urandom bs=4096 seek=7 count=2 of=file_with_holes
# output is shortened considerably
open("/dev/urandom", O_RDONLY)          = 0
open("file_with_holes", O_RDWR|O_CREAT, 0666) = 1
ftruncate(1, 28672)                     = 0
lseek(1, 28672, SEEK_CUR)               = 28672
read(0, "\244\212\222v\25\342\346\226\237\211\23\252\303\360\201\346@\351\6c.HF$Umt\362;E\233\261"..., 4096) = 4096
write(1, "\244\212\222v\25\342\346\226\237\211\23\252\303\360\201\346@\351\6c.HF$Umt\362;E\233\261"..., 4096) = 4096
read(0, "~\212q\224\256\241\277\344V\204\204h\312\25pw9\34\270WM\267\274~\236\313|{\v\6i\22"..., 4096) = 4096
write(1, "~\212q\224\256\241\277\344V\204\204h\312\25pw9\34\270WM\267\274~\236\313|{\v\6i\22"..., 4096) = 4096
close(0)                                = 0
close(1)                                = 0
write(2, "2+0 records in\n2+0 records out\n", 312+0 records in
2+0 records out
) = 31
write(2, "8192 bytes (8.2 kB) copied", 268192 bytes (8.2 kB) copied) = 26
write(2, ", 0.00104527 s, 7.8 MB/s\n", 25, 0.00104527 s, 7.8 MB/s
) = 25
+++ exited with 0 +++

Он открывается /dev/urandomдля чтения ( if=/dev/urandom), открывается file_with_holesдля создания / записи ( of=file_with_holes).

Затем он усекается file_with_holesдо 4096*7= 28672bytes ( bs=4096 seek=7). Сокращение означает, что содержимое файла после этой позиции теряется. (Добавьте, conv=notruncчтобы избежать этого шага). Затем он стремится к 28672байту.

Затем он читает 4096байты ( bs=4096используется как ibs) /dev/urandom, записывает 4096байты ( bs=4096используется как obs) file_with_holes, а затем выполняется другое чтение и запись ( count=2).

Затем он закрывает /dev/urandom, закрывает file_with_holesи печатает, что скопировал 2*4096= 8192байт. Наконец он выходит без ошибки (0).

frostschutz
источник
5

obsразмер выходного блока и размер ibsвходного блока. Если вы укажете bsбез ibsили obsэто используется для обоих.

Таким образом, ваш поиск будет 7 блоков по 4096 или 28672 байта в начале вашего вывода. Затем вы скопируете 2 блока по 4096 или 8192 байта от начала ввода до этой точки вывода.

Graeme
источник
1

Seek просто «раздувает» выходной файл. Seek = 7 означает, что в начале выходного файла будут вставлены 7 «пустых» блоков с размером выходного блока = obs = 4096 байт. Это способ быстро создавать очень большие файлы.

Торстен Стэрк
источник
1
Или пропустить данные в начале, которые вы не хотите изменять. Пустые блоки появляются только в том случае, если в выходном файле изначально не было такого количества данных. В руководстве также не ясно, как obsотносится bsкоманда, bsкоторая будет заменять ее, obsесли ее там нет.
Грэм,