임의의 데이터가 포함된 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
경고를 설명할 수 없습니다. 그것은 무엇을 말하는가? 경고 후 내 파일이 정말 무작위인가요, 아니면 뭔가 문제가 있나요? 800950+1 Datensätze ein
+0 또는 +1은 무엇을 800950+0 Datensätze aus
의미하나요? 경고 후 +1. 오류 횟수인가요?
답변1
요약: dd
올바르게 사용하기 어려운 이상한 도구입니다. 이에 대해 설명하는 수많은 튜토리얼이 있지만 사용하지 마세요. dd
"유닉스 거리의 신임" 분위기가 있습니다. 그러나 자신이 하고 있는 일을 정말로 이해한다면 10피트 기둥을 건드려서는 안 된다는 것을 알게 될 것입니다.
dd
각 블록은 시스템 호출 read
( 값으로 정의됨 bs
)을 한 번 호출합니다. read
시스템 호출이 지정된 버퍼 크기만큼의 데이터를 반환한다는 보장은 없습니다 . 이는 일반적으로 일반 파일 및 블록 장치에서는 작동하지만 파이프 및 일부 문자 장치에서는 작동하지 않습니다. 바라보다dd는 언제 데이터 복사에 적합합니까? (또는 read() 및 write()가 부분적인 경우)더 많은 정보를 알고 싶습니다. read
시스템 호출이 전체 데이터 블록보다 적은 데이터를 반환하는 경우 dd
부분 블록이 전송됩니다. 여전히 지정된 수의 블록을 복사하므로 전송된 총 바이트 수는 요청된 바이트 수보다 적습니다.
"부분 읽기"에 대한 경고는 정확히 다음과 같이 알려줍니다. 읽기 중 하나가 부분 읽기이므로 dd
불완전한 블록이 전송되었습니다. 블록 수에서 는 +1
블록이 부분적으로 읽혔음을 의미합니다. 출력 개수가 이므로 +0
모든 블록이 읽기로 기록됩니다.
이는 데이터의 무작위성에 영향을 주지 않습니다. dd
기록된 모든 바이트는 에서 읽은 바이트입니다 /dev/urandom
. 그러나 예상보다 적은 바이트를 얻습니다.
Linux는 /dev/urandom
임의로 대규모 요청을 처리할 수 있습니다(출처:extract_entropy_user
) drivers/char/random.c
이므로 dd
일반적으로 읽어도 안전합니다. 그러나 많은 양의 데이터를 읽으려면 시간이 걸립니다. 프로세스가 신호를 받으면 read
출력 버퍼를 채우기 전에 시스템 호출이 반환됩니다. 이는 정상적인 동작이며 read
루프에서 애플리케이션에 의해 호출되어야 합니다 . dd
역사적 이유로 그렇게 하지 않습니다( dd
그 기원은 모호하지만 특별한 요구 사항이 있었고 결코 적응되지 않은 테이프에 액세스하는 도구로 시작된 것 같습니다). 일반적인 도구). 진행 상황을 확인하면 dd
읽기를 중단하는 프로세스에 신호가 전송됩니다. 총 복사된 바이트 수를 확인하거나 dd
(중단하지 마십시오. 진행률 확인이나 일시 중지 없음) dd
지금까지 복사된 바이트 수를 알 수 있습니다. 이 경우 바이트 수를 알 수 없습니다. 바이트가 남아 있습니다. 복사할 바이트입니다.
버전dd
GNU coreutils에서fullblock
(비임베디드 Linux 및 Cygwin에서 발견됨)에는 루프에서 호출하라는 플래그가 있으므로 dd
(for와 동일) 전체 청크가 항상 전송됩니다. 오류 메시지에서는 이를 사용하라고 조언합니다. 매우 특수한 상황(주로 테이프에 액세스할 때)을 제외하고는 항상 입력 및 출력 플래그에 사용해야 합니다. 이를 사용하는 경우 일반적으로 더 좋은 솔루션이 있습니다(참조). 아래에).read
write
dd
dd if=/dev/urandom iflag=fullblock of=file bs=1M count=1000000
dd
수행할 작업을 결정하는 또 다른 방법은 청크 크기가 1인 청크를 전달하는 것입니다. 그런 다음 블록 수에서 복사된 바이트 수를 알 수 있습니다. 단, 첫 번째 블록을 읽기 전에 a가 중단되면 어떤 일이 발생할지 잘 모르겠습니다 read
(실제로는 가능성이 낮지만 발생할 수 있음). 그러나 작동하더라도 매우 느립니다.
일반적인 사용 권장 사항 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
). 그러나 파이프라인의 추가 항목이 필요합니다(성능 측면에서는 거의 눈에 띄지 않음).
답변2
dd
단일 읽기에서 블록을 채우기에 충분한 데이터를 얻을 수 없으면 경고가 나타납니다. 이는 불안정하거나 느린 데이터 소스 또는 요청한 블록 크기보다 작은 단위로 데이터를 쓰는 소스에서 발생합니다.
데이터 무결성에는 문제가 없지만 dd
부분 읽기가 여전히 읽기 블록으로 계산된다는 문제가 있습니다.
이 옵션을 사용하지 않으면 count
경고는 거의 중요하지 않으며 단지 성능만을 고려한 것입니다. 그러나 사용하면 count
요청한 양의 데이터를 얻을 수 없습니다. 부분적인 읽기로 인해 이전보다 작아 of
집니다 .count*bs
따라서 사용할 때는 기술적으로 count
도 항상 사용해야 합니다.iflag=fullblock
+x
부분 블록의 수 여야 합니다.
답변3
< /dev/urandom \
dd ibs=4k obs=64k |
dd bs=64k count=16000000 >file
^그렇습니다. 여기에 있는 오류 메시지는 분명히 잘못된 것입니다. dd
버퍼는분명히따라서 버퍼링된 입력계산이벤트를 명시적으로 버퍼링해야 합니다. 그게 다야. 똥을 사지 마세요.