우분투 시스템에서 다음 명령을 실행합니다.
dd if=/dev/random of=rand bs=1K count=2
그러나 실행할 때마다 크기가 다른 파일이 나타납니다. 왜 이런거야? 임의의 데이터로 채워진 주어진 크기의 파일을 생성하는 방법은 무엇입니까?
답변1
당신이 관찰하고 있는 특별한 행동은 dd
Linux의 특별한 행동의 조합입니다 /dev/random
. 그건 그렇고, 어느 쪽도 작업에 적합한 도구는 아닙니다.
Linux는 /dev/random
데이터를 거의 반환하지 않습니다. 이는 의사 난수 생성기의 엔트로피가 매우 빠르게 사라진다는 가정에 기초합니다. 새로운 엔트로피는 천천히 수집되므로 /dev/random
일반적으로 한 번에 몇 바이트만 제공됩니다.
dd
원래 테이프 장치에서 실행되도록 설계된 오래되고 기발한 프로그램입니다. 1kB 블록을 읽으라고 지시하면 블록 읽기를 시도합니다. 읽기에서 1024바이트 미만을 반환하면 그게 전부입니다. 그래서 두 번이나 전화를 dd if=/dev/random bs=1K count=2
걸었습니다 . read(2)
에서 읽기 때문에 /dev/random
이 두 read
호출은 일반적으로 사용 가능한 엔트로피에 따라 달라지는 몇 바이트만 반환합니다. 당신은 또한 볼 수 있습니다dd는 언제 데이터 복사에 적합합니까? (또는 read() 및 write()가 부분적인 경우)
운영 체제 설치 프로그램이나 복제 프로그램을 설계하지 않는 한 /dev/random
Linux에서는 절대 사용 해서는 안 됩니다 /dev/urandom
. 매뉴얼 urandom
페이지는 약간 오해의 소지가 있습니다. /dev/urandom
실제로는 암호화에 작동하며 장기 키를 생성할 수도 있습니다. 유일한 제한 /dev/urandom
은 충분한 엔트로피를 제공해야 한다는 것입니다. Linux 배포판은 일반적으로 재부팅 사이에 엔트로피를 저장하므로 새로 설치할 때에만 엔트로피가 충분하지 않을 수 있습니다. 사실 엔트로피는 절대 사라지지 않습니다. 더 많은 정보를 원하시면 읽어주세요/dev/urandom의 rand는 로그인 키에 안전합니까?그리고피드 /dev/랜덤 엔트로피 풀?.
의 대부분의 용도는 dd
와 같은 도구를 통해 더 잘 표현할 수 있습니다. 2kB의 임의 바이트를 원하면 다음을 실행하십시오.head
tail
head -c 2k </dev/urandom >rand
이전 Linux 커널을 사용하면 벗어날 수 있습니다.
dd if=/dev/urandom of=rand bs=1k count=2
/dev/urandom
요청한 만큼의 바이트를 반환하는 것이 좋기 때문입니다 . 그러나 커널 3.16부터는 더 이상 그렇지 않습니다.이제 32MB로 제한됩니다..
일반적으로 고정된 수의 바이트를 추출해야 dd
하고 해당 입력이 일반 파일이나 블록 장치에서 나오지 않는 경우 바이트 단위로 읽어야 합니다 dd bs=1 count=2048
.
답변2
man 4 random
RHEL 5 상자 에서 :
읽을 때 /dev/random 장치는 엔트로피 풀의 예상 노이즈 비트 수 내에서 임의 바이트만 반환합니다.
해당 컴퓨터에서 파일 크기는 213바이트입니다. 무작위로 Men 4로 돌아가기:
읽을 때 /dev/urandom 장치는 요청된 바이트 수를 반환합니다.
각 호출에서 2048바이트를 얻습니다.dd if=/dev/urandom of=rand bs=1K count=2
내 결론은 차이가 호출 사이에 기계가 생성하는 엔트로피의 양 때문이라는 것입니다.dd if=/dev/random ...
답변3
데이터가 손실되는 이유는 무엇입니까 dd
? ...자일스이 흥미로운 질문이 제기되었습니다 dd
.
dd는 언제 데이터 복사에 적합합니까? (또는 read() 및 write()가 부분적인 경우)
다음은 질문에서 발췌한 내용입니다.
*...오류에 대해 dd를 비난하는 것은 어렵지 않습니다. 예를 들어 다음 코드를 시도해 보세요. **
yes | dd of=out bs=1024k count=10
그리고 출력 파일의 크기를 확인하세요(아마도 10MB보다 훨씬 작을 것입니다).
귀하의 질문 끝에 있는 내 의견 외에도 이와 같은 내용은 볼만한 가치가 있습니다. 파일의 바이트를 캡처합니다 $trnd
. bs=8을 반 임의로 선택했습니다.
마우스를 움직여 속도를 관찰해 보세요.
내 컴퓨터가 유휴 상태일 때(AFK 및 네트워크 활동 없음) 엔트로피 풀을 소진한 후2시간12분수집만 한다1192 화바이트, 그 시점에서 취소했습니다.
그러다가 마우스를 계속 움직이다보니 상대적으로 시간이 덜 걸리더라구요1분15초동일한 수의 바이트를 수집합니다.
이는 엔트로피 수집이 CPU 속도가 아니라무작위 이벤트기반으로 내 Ubuntu 시스템은 마우스를 다음 중 하나로 사용합니다.중요한무작위 요인.
get=2048
trnd=/tmp/$USER.rnd; >"$trnd"
while (( $(wc -c <"$trnd") < $get )) ;do
dd if=/dev/random bs=8 count=1 2>/dev/null >>"$trnd"
echo -n "itt: $((i+=1)) ct: "; wc -c <"$trnd"
done
truncate -s $get "$trnd"
echo -e "\nfinal count: "; wc -c <"$trnd"
답변4
dd
예디자인됨차단용 - 일반적으로 필요한 경우 가변 크기 입력에서 데이터를 읽는 데 사용할 수 있는 가장 좋은 도구입니다.곧dd
현재 읽기는 미래로 버퍼링되지 않기 때문에write()
(ibs보다 더 큰 obs로 명시적으로 구성하지 않는 한), 그러나 읽은 모든 내용을 write()
즉시 읽습니다.read()
(그리고 선택적으로 처리).
다음은 몇 가지 중요한 사항입니다.정의:
ibs=
expr
- 입력 블록 크기를 바이트 단위로 지정합니다.
expr
(기본값은 512입니다).
- 입력 블록 크기를 바이트 단위로 지정합니다.
obs=
expr
- 출력 블록 크기를 바이트 단위로 지정
expr
(기본값은 512입니다).
- 출력 블록 크기를 바이트 단위로 지정
bs=
expr
- 입력 및 출력 블록 크기를 다음으로 설정합니다.
expr
, ,ibs=
및obs=
이외의 변환이 지정되지 않은 경우 각 입력 블록은 짧은 블록을 집계하지 않고 단일 블록으로 출력에 복사되어야 합니다.sync
noerror
notrunc
- 입력 및 출력 블록 크기를 다음으로 설정합니다.
따라서 ibs
과 가 obs
함께 정의 bs
되면 ibs
우선순위를 갖습니다. 그러나 그렇지 않은 경우에는 obs
또는 중 하나가 우선합니다 cbs
.
이것은 가장 중요한 예입니다 ibs
. 수영장이 가득 차는 데 걸리는 시간을 추적하고 싶다면 /dev/random
다음과 같이 할 수 있습니다.
dd "ibs=$size" conv=sync "count=$lmt" \
if=/dev/random of="$somefile"
if=
대상을 읽을 수 있는 한 ,언제나hronize는 null 값을 읽는 것을 dd
방지하므로 동일한 크기의 출력 파일이 생성됩니다 . sync
즉, dd
read()
s가 시간의 입력 청크를 나타내고 파일이 2바이트, 8바이트, 12바이트, 2바이트, 4바이트를 반환하는 $((size=10))
$((count=5))
경우 출력 파일은 다음과 유사합니다.read()
dd
2 read bytes 8NULs \
8 read bytes 2NULs \
10 read bytes 0NULs \
4 read bytes 6NULs \
4 read bytes 6NULs
... dd
기본적으로아니요지연. 따라서 스트림 내에서 다른 프로세스와 분리된 쓰기를 추적해야 하는 경우 dd
이 도구가 적합합니다.
특정 양의 데이터를 일반 파일에 쓰는 경우 여기에 작성된 다른 설명과 달리 dd
이 목적으로 매우 쉽게 사용할 수도 있지만 여러 데이터 조각과 안정적인 차단이 필요합니다.요인.
예를 들어, 다음과 같은 경우:
{ dd ibs="$size" obs="${size}x$block_factor" |
dd bs="${size}x$blockfactor" "count=$lmt"
} <infile >outfile
...첫 번째는 가능한 한 많은 입력 청크를 버퍼링하여 dd
두 번째 파이프와 파이프에 대한 출력 청크를 ibs="$size"
하나 이상 채웁니다 . obs="${size}x$block_factor"
이는 첫 번째 항목에서 생성된 모든 s가 해당 I/O 블록 크기와 일치하므로 두 번째 항목이 출력을 안정적으로 제한할 수 있음을 의미합니다.write()
dd
dd
count="$lmt"
write()
에도 불구하고read()
dd
그렇게 하려면 첫 번째 사람이 얼마나 해야 합니까 ?
그리고저것이것은 dd
약간의 계산만으로 파이프나 기타 유형의 특수 파일을 안정적으로 읽을 수 있는 방법입니다.