와 함께 임의의 데이터로 1TB 파일을 만듭니다 dd if=/dev/urandom of=file bs=1M count=1000000
. 이제 kill -SIGUSR1 <PID>
진행 상황을 확인하고 다음을 얻습니다.
691581+0 Datensätze ein
691580+0 Datensätze aus
725174190080 Bytes (725 GB) kopiert, 86256,9 s, 8,4 MB/s
800950+1 Datensätze ein
800950+0 Datensätze aus
839856947200 Bytes (840 GB) kopiert, 99429,5 s, 8,4 MB/s
dd: warning: partial read (809620 bytes); suggest iflag=fullblock
803432+1 Datensätze ein
803431+1 Datensätze aus
842459273876 Bytes (842 GB) kopiert, 99791,3 s, 8,4 MB/s
경고를 해석 할 수 없습니다. 그것은 무엇을 말하는가? 경고 후 내 파일이 실제로 무작위입니까, 아니면 문제가 있습니까? 무엇 0 또는 1의 수행 800950+1 Datensätze ein
및 800950+0 Datensätze aus
평균? 경고 후 +1입니다. 오류 횟수입니까?
답변
요약 : dd
제대로 사용하기 어려운 까다로운 도구입니다. 수많은 자습서에도 불구하고 사용하지 마십시오. dd
“unix street cred”바이브가 부착되어 있습니다.하지만 당신이하고있는 일을 진정으로 이해한다면, 10 피트 기둥으로 만지면 안된다는 것을 알게 될 것입니다.
dd
read
블록 당 시스템 호출을 단일 호출합니다 (값으로 정의 됨 bs
). read
시스템 호출이 지정된 버퍼 크기만큼 많은 데이터를 리턴 한다는 보장은 없습니다 . 이것은 일반 파일 및 블록 장치에서는 작동하지만 파이프 및 일부 문자 장치에서는 작동하지 않습니다. dd가 데이터 복사에 적합한시기를 참조하십시오 . 자세한 내용 은 read () 및 write () 부분 일 때 경우 read
시스템 호출이 반환 미만 전체 블록, 다음 dd
부분 블록을 전송합니다. 여전히 지정된 수의 블록을 복사하므로 전송 된 총 바이트 수가 요청 된 것보다 적습니다.
“부분 읽기”에 대한 경고는 정확하게 이것을 알려줍니다. 읽기 중 하나는 부분적이므로 dd
불완전한 블록으로 전송되었습니다. 블록 카운트에서 +1
하나의 블록을 부분적으로 읽었 음을 의미합니다. 출력 카운트가 +0
이므로 모든 블록을 읽은 상태로 기록했습니다.
이것은 데이터의 임의성에 영향을 미치지 않습니다. dd
기록하는 모든 바이트 는에서 읽은 바이트입니다 /dev/urandom
. 그러나 예상보다 적은 바이트를 얻었습니다.
Linux는 /dev/urandom
임의의 큰 요청 (source : extract_entropy_user
in drivers/char/random.c
)을 수용하므로 dd
일반적으로 읽을 때 안전합니다. 그러나 많은 양의 데이터를 읽으려면 시간이 걸립니다. 프로세스가 신호를 수신하면 read
출력 버퍼를 채우기 전에 시스템 호출이 리턴됩니다. 이것은 정상적인 동작이며 응용 프로그램은 read
루프 를 호출해야합니다 . dd
역사적인 이유로 (이것은 dd
출처가 어둡지 만, 독특한 요구 사항을 가지고 있으며 범용 도구로 채택되지 않은 테이프에 액세스하는 도구로 시작된 것으로 보입니다). 진행 상황을 확인하면 dd
프로세스에 읽기를 방해하는 신호를 보냅니다 . 바이트 수를 아는 것 중에서 선택할 수 있습니다dd
전체 복사 (진행 확인, 일시 중단 없음) 또는 dd
지금까지 얼마나 많은 바이트 가 복사 되었는지 아는 경우 복사 할 바이트 수를 알 수 없습니다.
버전 dd
GNU의로 coreutils에서 (Cygwin에서 비 임베디드 리눅스와에 발견은) 플래그가 fullblock
알려줍니다 dd
호출 read
(및 저두 루프 write
) 때문에 항상 전체 블록을 전송합니다. 오류 메시지는 사용을 제안합니다. 매우 특수한 상황 (주로 테이프에 액세스 할 때)을 제외하고는 항상 (입력 및 출력 플래그 모두) 사용해야합니다 dd
. 전혀 사용하지 않는 경우 : 일반적으로 더 나은 솔루션이 있습니다 (아래 참조).
dd if=/dev/urandom iflag=fullblock oflag=fullblock of=file bs=1M count=1000000
dd
수행 할 작업을 확인하는 또 다른 가능한 방법 은 블록 크기 1을 전달하는 것입니다. 그런 다음 read
첫 번째를 읽기 전에 a 가 중단 되면 어떻게 될지 잘 모르겠지만 블록 수에서 복사 된 바이트 수를 알 수 있습니다 바이트 (실제로는 아니지만 가능성이 있음). 그러나 작동하더라도 매우 느립니다.
사용에 대한 일반적인 조언 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
.
답변
dd
단일 읽기에서 블록을 채우기에 충분한 데이터를 얻을 수 없을 때 경고가 발생합니다 . 이는 불규칙하거나 느린 데이터 소스 또는 요청 된 블록 크기보다 작은 단위로 데이터를 쓰는 소스에서 발생합니다.
데이터 무결성에는 문제가 없지만 dd
부분 읽기는 여전히 읽기 블록으로 간주됩니다.
count
옵션을 사용하지 않는 경우 경고는 거의 중요 하지 않으며 성능 고려 사항 일뿐입니다. 그러나을 (를) 사용 count
하면 요청한 데이터 양을 얻을 수 없습니다. 부분 읽기로 인해 끝 of
보다 작습니다 count*bs
.
따라서를 사용할 count
때는 기술적으로 항상 사용해야 iflag=fullblock
합니다.
은 +x
부분 블록의 개수이어야한다.
답변
< /dev/urandom \
dd ibs=4k obs=64k |
dd bs=64k count=16000000 >file
^ 그냥 작동합니다. 그렇지 않은 경우 잘못된 정보는 명백히 거짓입니다. dd
의 버퍼는 명시 적이므로 발생 을 계산 하기 위해 입력을 버퍼링하려면 명시 적으로 버퍼링해야합니다. 그게 다야 똥을 사지 마십시오.