Argumento 'seek' no comando dd

20

Alguns podem me explicar o que está acontecendo nas seguintes linhas?

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

especialmente procurar parte não é clara

As páginas de manual dizem:

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

O que é um bloco obsoleto?

user2799508
fonte

Respostas:

22

ddfoi projetado para copiar blocos de dados de um arquivo de entrada para um arquivo de saída. As ddopções de tamanho do bloco são as seguintes, na página de manual :

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=.

A dd seekopção é semelhante à lseek()chamada 1 do sistema UNIX . Move o ponteiro de leitura / gravação dentro do arquivo. Na página do manual :

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

Os arquivos comuns no UNIX têm a propriedade conveniente de que você não precisa lê-los ou gravá-los começando no início; você pode procurar em qualquer lugar e ler ou escrever a partir daí. Então, bs=4096 seek=7significa mover para uma posição 7 * 4096 bytes desde o início do arquivo de saída e começar a escrever a partir daí. Ele não será gravado na parte do arquivo entre 0 e 7 * 4096 bytes.

Áreas de arquivos comuns que nunca são gravadas nem são alocadas pelo sistema de arquivos subjacente. Essas áreas são chamadas de buracos e os arquivos são chamados de arquivos esparsos . No seu exemplo, file_with_holeshaverá um furo de 7 * 4096 bytes no início. (h / t @frostschutz por apontar que ddtrunca o arquivo de saída por padrão.)

Não há problema em ler essas áreas não alocadas; você recebe um monte de zeros.

[1] quando ddfoi gravada, a chamada do sistema análoga foi seek().

Mark Plotnick
fonte
Interessante, minha página de manual é irritantemente imprevisível quanto a isso - `bs = BYTES lê e grava em bytes de bytes de cada vez` #
Graeme
Eu não vi "procurar" no UNIX, talvez "lseek", eu acho.
kangear
1
Apenas a nota, eu estava tentando buscar um dispositivo de acionamento (exmaple: dd if=/dev/zero bs=512 count=2 seek=8388607998 of=/dev/sdd), mas os 'arquivos' / descritores não são pesquisável: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
Pysis
1
Os dispositivos de disco @Pysis geralmente são procuráveis, mas talvez haja alguns problemas com dispositivos muito grandes. Qual o tamanho (em bytes) do seu / dev / sdd?
Mark Plotnick
1
Talvez eu tenha antes e não me lembro. Estou tentando acessar o setor GPT de backup ou 2 no final de um disco de 4 TB.
Pysis
6

As outras respostas já explicaram isso, mas se você tiver alguma dúvida, pode ver o que ddfaz 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 +++

Abre /dev/urandompara leitura ( if=/dev/urandom), abre file_with_holespara criar / escrever ( of=file_with_holes).

Em seguida, trunca file_with_holespara 4096*7= 28672bytes ( bs=4096 seek=7). O truncado significa que o conteúdo do arquivo após essa posição é perdido. (Adicione conv=notruncpara evitar esta etapa). Então ele procura 28672bytes.

Em seguida, ele lê 4096bytes ( bs=4096usados ​​como ibs) de /dev/urandom, grava 4096bytes ( bs=4096usados ​​como obs) em file_with_holes, seguidos por outra leitura e gravação ( count=2).

Em seguida, fecha /dev/urandom, fecha file_with_holese imprime que copiou 2*4096= 8192bytes. Finalmente, sai sem erro (0).

frostschutz
fonte
5

obsé o tamanho do bloco de saída e ibsé o tamanho do bloco de entrada. Se você especificar bssem ibsou obsisso será usado para ambos.

Portanto, sua busca será de 7 blocos de 4096 ou 28672 bytes no início de sua saída. Em seguida, você copiará 2 blocos de 4096 ou 8192 bytes do início da entrada para este ponto na saída.

Graeme
fonte
1

A busca apenas "inflará" o arquivo de saída. Busca = 7 significa que no início do arquivo de saída, 7 blocos "vazios" com tamanho de bloco de saída = obs = 4096 bytes serão inseridos. Esta é uma maneira de criar arquivos muito grandes rapidamente.

Thorsten Staerk
fonte
1
Ou para pular os dados no início que você não deseja alterar. Blocos vazios somente resultam se o arquivo de saída inicialmente não tiver muitos dados. O manual também não está claro sobre como obsse relaciona bs, o comando usa o bsque substituirá obsse ele não estiver lá.
Graeme