dd 명령의 'seek'인수


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

obssized 블록이란 무엇입니까?

답변:


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 과 유사합니다 . 파일 내에서 읽기 / 쓰기 포인터를 이동합니다. 로부터 man 페이지 :

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기본적으로 출력 파일 을 자릅니다.)

이러한 할당되지 않은 영역을 읽는 것이 좋습니다. 당신은 많은 0을 얻습니다.

[1] 다시 dd쓰여졌을 때 비슷한 시스템 호출은이었다 seek().


흥미롭게도, 내 man 페이지는 이것에 대해 성가신 일입니다.`bs = BYTES 한 번에 BYTES 바이트까지 읽고 쓰기 '
Graeme

유닉스에서 "seek"를 보지 못했습니다. 아마도 "lseek"라고 생각합니다.
kangear

1
참고로, 드라이브 장치 (예 dd if=/dev/zero bs=512 count=2 seek=8388607998 of=/dev/sdddd: /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 Disk 장치는 일반적으로 검색 가능하지만 매우 큰 장치에는 몇 가지 문제가있을 수 있습니다. / dev / sdd는 몇 바이트입니까?
Mark Plotnick

1
어쩌면 내가 전에 기억하지 못할 수도 있습니다. 4TB 디스크 끝에서 백업 GPT 섹터 또는 2에 액세스하려고합니다.
Pysis

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_holes4096*7= 28672바이트 ( 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).


5

obs출력 블록 크기이며 ibs입력 블록 크기입니다. 당신은 지정하면 bs없이 ibs또는 obs이 모두를 위해 사용된다.

따라서 검색 시작시 4096 또는 28672 바이트의 7 블록이됩니다. 그런 다음 입력 시작에서 출력의이 지점까지 4096 또는 8192 바이트의 두 블록을 복사합니다.


1

찾기는 단지 출력 파일을 "팽창"시킵니다. Seek = 7은 출력 파일의 시작 부분에 출력 블록 size = obs = 4096bytes 인 "빈"블록 7 개가 삽입됨을 의미합니다. 이것은 매우 큰 파일을 빠르게 만드는 방법입니다.


1
또는 변경을 원하지 않는 시작 부분에서 데이터를 건너 뛸 수 있습니다. 빈 블록은 출력 파일에 처음에 많은 양의 데이터가없는 경우에만 발생합니다. 매뉴얼 obs과 관련 bs하여 명령이 명확하지 않은 경우 명령이 사용 bs되는 경우 대체 obs할 명령을 사용합니다 .
Graeme
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.