argument „seek” w poleceniu dd

20

Czy ktoś może mi wyjaśnić, co się dzieje w następujących wierszach?

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

szczególnie poszukiwanie części nie jest jasne

Strony podręcznika mówią:

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

Co to jest blok obs-size?

użytkownik2799508
źródło

Odpowiedzi:

22

ddjest przeznaczony do kopiowania bloków danych z pliku wejściowego do pliku wyjściowego. Te ddopcje rozmiaru bloku są następujące, od strony człowieka :

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

Ta dd seekopcja jest podobna do lseek()wywołania systemowego UNIX 1 . Przesuwa wskaźnik odczytu / zapisu w pliku. Od strony man :

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

Pliki zwykłe w systemie UNIX mają wygodną właściwość, której nie trzeba odczytywać ani zapisywać od samego początku; możesz szukać w dowolnym miejscu i czytać lub pisać od tego miejsca. Tak więc bs=4096 seek=7środki, aby przejść do pozycji 7 * 4096 bajtów od początku pliku wyjściowego i zacząć pisać stamtąd. Nie zapisuje do części pliku, która ma od 0 do 7 * 4096 bajtów.

Obszary zwykłych plików, do których nigdy nie są zapisywane, nie są nawet przydzielane przez podstawowy system plików. Te obszary są nazywane dziurami, a pliki nazywane są plikami rzadkimi . W twoim przykładzie file_with_holesbędzie miał na początku 7 * 4096 bajtowy otwór. (h / t @frostschutz za wskazanie, że dddomyślnie obcina plik wyjściowy).

Czytanie tych nieprzydzielonych obszarów jest w porządku; dostajesz garść zer.

[1] w czasie, gdy ddzostało napisane, analogiczne wywołanie systemowe było seek().

Mark Plotnick
źródło
Interesujące jest to, że moja strona podręcznika jest irytująco niegodna w tym temacie - `bs = BYTES odczytuj i zapisuj do bajtów BYTES jednocześnie '
Graeme
Nie widziałem „szukaj” w systemie UNIX, może „lseek”.
kangear
1
Dla przypomnienia starałem się znaleźć urządzenie napędowe (przykład:) dd if=/dev/zero bs=512 count=2 seek=8388607998 of=/dev/sdd, ale tych „plików” / deskryptorów nie można zobaczyć: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
Urządzenia @Pysis Disk są zwykle widoczne, ale być może występują problemy z bardzo dużymi urządzeniami. Jak duży (w bajtach) jest twój / dev / sdd?
Mark Plotnick
1
Może mam już i nie pamiętam. Próbuję uzyskać dostęp do zapasowego sektora GPT lub 2 na końcu dysku 4 TB.
Pysis
6

Inne odpowiedzi już to wyjaśniły, ale jeśli masz jakiekolwiek wątpliwości, możesz zobaczyć, co ddz tym zrobić 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 +++

Otwiera się /dev/urandomdo odczytu ( if=/dev/urandom), otwiera się file_with_holesdo tworzenia / zapisu ( of=file_with_holes).

Następnie obcina się file_with_holesdo 4096*7= 28672bytes ( bs=4096 seek=7). Obcięcie oznacza, że ​​zawartość pliku po tej pozycji zostanie utracona. (Dodaj, conv=notruncaby uniknąć tego kroku). Następnie szuka 28672bajtów.

Następnie odczytuje 4096bajty ( bs=4096używane jako ibs) z /dev/urandom, zapisuje 4096bajty ( bs=4096używane jako obs) do file_with_holes, a następnie kolejny odczyt i zapis ( count=2).

Następnie zamyka /dev/urandom, zamyka file_with_holesi drukuje, że skopiował 2*4096= 8192bajty. Wreszcie wychodzi bez błędu (0).

frostschutz
źródło
5

obsto rozmiar bloku wyjściowego i ibsrozmiar bloku wejściowego. Jeśli określisz opcję „ bsbez” ibslub „ obsto” zostanie użyte dla obu.

Więc twoje wyszukiwanie będzie miało 7 bloków po 4096 lub 28672 bajtów na początku twojego wyjścia. Następnie skopiujesz 2 bloki 4096 lub 8192 bajtów od początku wprowadzania do tego punktu na wyjściu.

Graeme
źródło
1

Seek po prostu „napompuje” plik wyjściowy. Seek = 7 oznacza, że ​​na początku pliku wyjściowego zostanie wstawionych 7 „pustych” bloków o rozmiarze bloku wyjściowego = obs = 4096 bajtów. Jest to sposób szybkiego tworzenia bardzo dużych plików.

Thorsten Staerk
źródło
1
Lub pomiń dane na początku, których nie chcesz zmieniać. Puste bloki powstają tylko wtedy, gdy plik wyjściowy początkowo nie zawierał tak dużej ilości danych. Podręcznik nie wyjaśnia również, w jaki sposób obsodnosi się do bspolecenia, bsktóre zastępuje, obsjeśli go nie ma.
Graeme