Twórz losowe dane za pomocą dd i uzyskaj „ostrzeżenie o częściowym odczycie”. Czy dane po ostrzeżeniu są teraz naprawdę losowe?


16

Tworzę plik 1 TB z losowymi danymi za pomocą dd if=/dev/urandom of=file bs=1M count=1000000. Teraz sprawdzam kill -SIGUSR1 <PID>postępy i otrzymuję:

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

Nie mogę zinterpretować ostrzeżenia. Co to mówi? Czy po ostrzeżeniu mój plik jest naprawdę losowy, czy występuje problem? Co +0 +1 lub w 800950+1 Datensätze eini 800950+0 Datensätze ausśrednią? Po ostrzeżeniu jest +1. Czy to liczba błędów?


Łatwiej byłoby odpowiedzieć, gdybyś mógł przetłumaczyć wiadomości na angielski. Zdefiniuj także „naprawdę losowy”. Jakiego poziomu losowości potrzebujesz, do czego go wykorzystasz?
terdon

Aby otrzymywać wiadomości w języku angielskim, użyj LC_ALL=Cprzed poleceniem, na przykładLC_ALL=C dd if=...
Volker Siegel

Odpowiedzi:


38

Podsumowanie: ddjest zepsutym narzędziem, które jest trudne w użyciu poprawnie. Nie używaj go, pomimo licznych samouczków, które ci to mówią. ddma w sobie klimat „unix street cred” - ale jeśli naprawdę rozumiesz, co robisz, będziesz wiedział, że nie powinieneś dotykać go 10-metrowym drągiem.

ddwykonuje pojedyncze wywołanie wywołania readsystemowego na blok (zdefiniowane przez wartość bs). Nie ma gwarancji, że readwywołanie systemowe zwróci tyle danych, ile podany rozmiar bufora. Zwykle działa to na zwykłe pliki i urządzenia blokujące, ale nie na potoki i niektóre urządzenia znakowe. Zobacz Kiedy dd nadaje się do kopiowania danych? (lub, gdy są czytane () i write () częściowe), aby uzyskać więcej informacji. Jeśli readwywołanie systemowe zwraca mniej niż jeden pełny blok, wówczas ddprzenosi blok częściowy. Nadal kopiuje określoną liczbę bloków, więc całkowita liczba przesłanych bajtów jest mniejsza niż wymagana.

Ostrzeżenie o „częściowym odczycie” mówi dokładnie to: jeden z odczytów był częściowy, więc ddprzekazano niepełny blok. W liczeniu bloków +1oznacza, że ​​jeden blok został częściowo odczytany; ponieważ liczba wyjść jest taka +0, wszystkie bloki zostały zapisane jako przeczytane.

Nie wpływa to na losowość danych: wszystkie bajty, które ddwypisują, są bajtami, które odczytały /dev/urandom. Ale masz mniej bajtów niż oczekiwano.

Linux /dev/urandomobsługuje dowolne duże żądania (source: extract_entropy_userin drivers/char/random.c), więc ddzwykle jest bezpieczny podczas czytania z niego. Jednak czytanie dużych ilości danych wymaga czasu. Jeśli proces odbierze sygnał, readwywołanie systemowe powraca przed zapełnieniem bufora wyjściowego. Jest to normalne zachowanie, a aplikacje powinny wywoływać się readw pętli; ddnie robi tego z przyczyn historycznych ( ddpochodzenie jest niejasne, ale wydaje się, że zaczęło się jako narzędzie dostępu do taśm, które mają specyficzne wymagania i nigdy nie zostało przystosowane do tego, by być narzędziem ogólnego zastosowania). Gdy sprawdzasz postęp, wysyła do ddprocesu sygnał, który przerywa odczyt. Masz wybór między wiedzą, ile bajtówddskopiuje w całości (pamiętaj, aby go nie przerwać - bez sprawdzania postępu, bez zawieszenia) lub wiedząc, ile bajtów ddskopiowano do tej pory, w takim przypadku nie możesz wiedzieć, ile jeszcze bajtów skopiuje.

Wersja ddw GNU coreutils (znaleziona w niewbudowanym systemie Linux i na Cygwin) ma flagę, fullblockktóra mówi, ddaby wywoływać readw pętli (i to samo dla write), a zatem zawsze przenosić pełne bloki. Komunikat o błędzie sugeruje jego użycie; powinieneś zawsze go używać (zarówno w flagach wejściowych, jak i wyjściowych), z wyjątkiem bardzo szczególnych okoliczności (głównie podczas uzyskiwania dostępu do taśm) - jeśli ddw ogóle używasz , to znaczy: zwykle są lepsze rozwiązania (patrz poniżej).

dd if=/dev/urandom iflag=fullblock oflag=fullblock of=file bs=1M count=1000000

Innym możliwym sposobem na upewnienie się, co się ddstanie, jest przekazanie bloku o rozmiarze 1. Następnie możesz powiedzieć, ile bajtów zostało skopiowanych z liczby bloków, chociaż nie jestem pewien, co się stanie, jeśli a readzostanie przerwane przed przeczytaniem pierwszego bajt (co w praktyce jest mało prawdopodobne, ale może się zdarzyć). Jednak nawet jeśli to działa, jest to bardzo powolne.

Według opinii na temat używania ddjest nie używaćdd . Chociaż ddjest często reklamowany jako polecenie niskiego poziomu dostępu do urządzeń, w rzeczywistości nie ma takiej rzeczy: cała magia dzieje się w części pliku urządzenia /dev/…, ddjest zwykłym narzędziem o wysokim potencjale niewłaściwego użycia powodującego utratę danych . W większości przypadków istnieje prostszy i bezpieczniejszy sposób robienia tego, co chcesz, przynajmniej w systemie Linux.

Na przykład, aby odczytać określoną liczbę bajtów na początku pliku, wystarczy wywołać head:

head -c 1000000m </dev/urandom >file

Zrobiłem szybki test porównawczy na mojej maszynie i nie zauważyłem żadnej różnicy w wydajności między dddużym blokiem a head.

Jeśli musisz pominąć kilka bajtów na początku, potokuj taildo head:

dd if=input of=output count=C bs=B seek=S
<input tail -c +$((S*B+1)) | head -c $((C*B)) >output

Jeśli chcesz zobaczyć postęp, zadzwoń, lsofaby zobaczyć przesunięcie pliku. Działa to tylko na zwykłym pliku (plik wyjściowy na twoim przykładzie), a nie na urządzeniu znakowym.

lsof -a -p 1234 -d 1
cat /proc/1234/fdinfo/1

Możesz zadzwonić, pvaby uzyskać raport postępu (lepszy niż dd), kosztem dodatkowego elementu w potoku (pod względem wydajności jest to ledwo zauważalne).


2
+1. Jest to jeden z najlepiej zbadanych postów, jaki czytałem w sieci StackExchange od dłuższego czasu. Jest zwięzły, ale zawiera wszystkie szczegóły (historyczne i współczesne) na temat ddpolecenia, o którym nie wiedziałem, że powinienem wiedzieć. Dzięki.
Cosmic Ossifrage

4
Przykro mi, ale nie zgadzam się z twoją tezą, że dd jest „zepsutym narzędziem, które trudno używać poprawnie” i „nie używaj dd”. Jest to doskonale użyteczne narzędzie, jeśli jest właściwie używane przez kogoś, kto poświęcił czas na jego zrozumienie. Rzeczywiście, dyskowe zestawy narzędzi sądowych prawie wszystkie zależą od dd lub pochodnej takiej jak dcfldd.
fpmurphy

1
@ fpmurphy1 GNU ddmoże być bezpiecznie używany, dzięki jego fullblockopcji. Ale jeśli masz jądra GNU, nie potrzebujesz ddwiele. „Pochodne”, dcflddktóre niedd, nie mają wad konstrukcyjnych, więc moja odpowiedź ich nie dotyczy. Ogromna większość ludzi, którzy używają dd, nie poświęciła wystarczająco dużo czasu na jej zrozumienie (najwyżej poświęciła czas, by myśleć , że to rozumie), a sposób, w jaki z niego korzystają, prowadzi do utraty danych.
Gilles „SO- przestań być zły”

1
@Gilles Więc nie powinniśmy używać „echo” b / c jego potencjalnego niewłaściwego użycia (sudo echo hello world> / dev / sda)?
whitey04,

2
@ whitey04 Polecam nie obchodzić się z beczkami nitrogliceryny. Nie powiedziałem, że nie powinieneś używać zapałek.
Gilles „SO- przestań być zły”

9

Ostrzeżenie pojawia się, gdy ddnie można uzyskać wystarczającej ilości danych, aby wypełnić blok w jednym odczycie. Dzieje się tak w przypadku nieregularnych lub wolnych źródeł danych lub źródeł zapisujących dane w mniejszych jednostkach niż żądany rozmiar bloku.

Nie ma problemu z integralnością danych, ale problem polega na tym, że ddczęściowy odczyt nadal jest traktowany jako blok odczytu.

Jeśli nie korzystasz z tej countopcji, ostrzeżenie nie ma większego znaczenia, to tylko kwestia wydajności. Ale dzięki countnie uzyskasz żądanej ilości danych. Ze względu na częściowe odczyty ofbędą mniejsze niż count*bsna końcu.

Więc kiedy używasz count, technicznie powinieneś zawsze również używać iflag=fullblock.

+xPowinna być liczba częściowych bloków.


-3
< /dev/urandom \
dd ibs=4k obs=64k |
dd bs=64k count=16000000 >file

^ To po prostu zadziała. W przeciwnym razie błędne informacje są oczywiście fałszywe. ddBufory są jawne, więc aby buforować dane wejściowe w celu zliczenia wystąpień, musisz je jawnie buforować. To wszystko. Nie kupuj dziwki.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.