Chciałem utworzyć losowy plik 1 GB, więc użyłem następującego polecenia.
dd if=/dev/urandom of=output bs=1G count=1
Zamiast tego za każdym razem, gdy uruchamiam to polecenie, otrzymuję plik 32 MB:
<11:58:40>$ dd if=/dev/urandom of=output bs=1G count=1
0+1 records in
0+1 records out
33554431 bytes (34 MB, 32 MiB) copied, 0,288321 s, 116 MB/s
Co jest nie tak?
EDYTOWAĆ:
Dzięki świetnym odpowiedziom w tym temacie doszedłem do rozwiązania, które odczytuje 32 fragmenty o wielkości 32 MB, co daje 1 GB:
dd if=/dev/urandom of=output bs=32M count=32
Podano inne rozwiązanie, które odczytuje 1 GB bezpośrednio do pamięci, a następnie zapisuje na dysku. To rozwiązanie zajmuje dużo pamięci, więc nie jest preferowane:
dd if=/dev/urandom of=output bs=1G count=1 iflag=fullblock
script
dd
random-number-generator
Trismegistos
źródło
źródło
dd
. Używałbymhead
,cat
alborsync
prawie zawsze na swoim miejscu. I twoje pytanie, czy jeden z powodów, dla których alternatywy są zwykle bezpieczniejsze.head
nie może wykonać tego zadania bez-c
opcji, która nie jest w POSIX . Nie znam żadnej wersji,cat
która mogłaby to rozwiązać.rsync
jest całkowicie niestandardowym narzędziem. Tego tu nie ma; przeglądając stronę podręcznika, nie widzę też, jak mógłby rozwiązać ten problem./dev/urandom
nie ma go również w POSIX ...Odpowiedzi:
bs
, rozmiar bufora, oznacza rozmiar pojedynczego wywołania read () wykonanego przez dd.(Na przykład zarówno
bs=1M count=1
ibs=1k count=1k
spowoduje powstanie pliku 1 MiB, ale pierwsza wersja zrobi to w jednym kroku, a druga zrobi to w 1024 małych porcjach.)Zwykłe pliki mogą być odczytywane przy prawie dowolnym rozmiarze bufora (o ile bufor ten mieści się w pamięci RAM), ale urządzenia i pliki „wirtualne” często działają bardzo blisko poszczególnych wywołań i mają pewne arbitralne ograniczenie ilości danych, które będą wytwarzać na Wywołanie read ().
Za
/dev/urandom
granica ta jest zdefiniowana w urandom_read () w drivers / char / random.c :Oznacza to, że za każdym razem, gdy wywoływana jest funkcja, żądany rozmiar zostanie ograniczony do 33554431 bajtów.
Domyślnie, w przeciwieństwie do większości innych narzędzi, dd nie będzie ponawiać próby po otrzymaniu mniejszej ilości danych niż zażądano - dostajesz 32 MiB i to wszystko. (Aby ponownie spróbować automatycznie, tak jak w odpowiedzi Kamila, musisz określić
iflag=fullblock
.)Zauważ też, że „rozmiar pojedynczego odczytu ()” oznacza, że cały bufor musi jednocześnie zmieścić się w pamięci, więc ogromne rozmiary bloków również odpowiadają ogromnemu zużyciu pamięci przez dd .
I to wszystko nie ma sensu, ponieważ zwykle nie osiągniesz żadnej wydajności, gdy przekroczysz ~ 16–32 bloków MiB - wywołania systemowe nie są tutaj wolną częścią, generator liczb losowych jest.
Więc dla uproszczenia, po prostu użyj
head -c 1G /dev/urandom > output
.źródło
iflag=fullblock
jest to rozszerzenie GNU do narzędzia POSIXdd
. Ponieważ pytanie nie określa Linuksa, myślę, że użycie rozszerzeń specyficznych dla Linuksa powinno być wyraźnie odnotowane, aby jakiś przyszły czytelnik nie próbował pomylić podobnego problemu w systemie innym niż Linux.dd
na moim komputerze, z rozmiarami bloków od 1k do 512M. Odczyt z dysku SSD Intel 750, optymalna wydajność (około 1300 Mb / s) została osiągnięta przy blokach 2 MB, mniej więcej odpowiadając twoim wynikom. Większe rozmiary bloków nie pomagały ani nie przeszkadzały. Odczyt z/dev/zero
, optymalna wydajność (prawie 20GiB / s) wynosiła 64KiB i 128KiB; zarówno mniejsze, jak i większe bloki zmniejszały wydajność, mniej więcej odpowiadając mojemu poprzedniemu komentarzowi. Konkluzja: punkt odniesienia dla Twojej aktualnej sytuacji. I oczywiście żadne z nas nie przeprowadziło testu porównawczego/dev/random
: Pdd
szybszych testów i wygląda na to , że jest szybszy. Szybki przegląd pokazał, żehead
używa odczytów 8KiB i dwóch zapisów 4KiB, co jest interesujące (GNU coreutils 8.26 w Debianie 9.6 / Linux 4.8).head
prędkości są rzeczywiście gdzieś pomiędzydd bs=4k
add bs=8k
.head
prędkości spadają ~ 40% w porównaniu dodd if=/dev/zero bs=64k
i spadają ~ 25% w porównaniu dodd if=/dev/nvme0n1 bs=2M
. Odczyty z/dev/zero
są oczywiście bardziej ograniczone przez procesor, ale w przypadku SSD kolejkowanie we / wy również odgrywa pewną rolę. To większa różnica, niż się spodziewałem.dd
może odczytać mniej niżibs
(uwaga:bs
określa jednoibs
i drugieobs
), chyba żeiflag=fullblock
podano inaczej .0+1 records in
wskazuje, że0
pełne bloki i1
blok częściowy zostały odczytane. Jednak każdy pełny lub częściowy blok zwiększa licznik.Nie znam dokładnego mechanizmu, który powoduje, żeEdycja: ta współbieżna odpowiedź wyjaśnia mechanizm, który powoduje, żedd
odczyt bloku jest mniejszy niż1G
w tym konkretnym przypadku. Chyba jakikolwiek blok jest odczytywany do pamięci przed jego zapisaniem, więc zarządzanie pamięcią może przeszkadzać (ale to tylko przypuszczenie).dd
odczyt bloku jest mniejszy niż1G
w tym konkretnym przypadku.W każdym razie nie polecam tak dużych
bs
. Chciałbym użyćbs=1M count=1024
. Najważniejsze jest to: beziflag=fullblock
żadnej próby odczytu może odczytać mniej niżibs
(chybaibs=1
, że myślę, że jest to dość nieefektywne).Więc jeśli chcesz odczytać dokładną ilość danych, użyj
iflag=fullblock
. Uwagaiflag
nie jest wymagana przez POSIX,dd
możesz jej nie obsługiwać. Zgodnie z tą odpowiedziąibs=1
jest to prawdopodobnie jedyny sposób POSIX-a na odczyt dokładnej liczby bajtów. Oczywiście, jeśli zmieniszibs
, będziesz musiał ponownie obliczyćcount
. W twoim przypadku obniżenieibs
do32M
lub mniej prawdopodobnie rozwiąże problem, nawet beziflag=fullblock
.W moim Kubuntu naprawiłbym twoje polecenie w następujący sposób:
źródło