Tạo dữ liệu ngẫu nhiên với dd và nhận được cảnh báo đọc một phần của Google. Là dữ liệu sau khi cảnh báo bây giờ thực sự ngẫu nhiên?


16

Tôi tạo một tệp 1TB với dữ liệu ngẫu nhiên với dd if=/dev/urandom of=file bs=1M count=1000000. Bây giờ tôi kiểm tra kill -SIGUSR1 <PID>tiến độ và nhận được những điều sau đây:

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

Tôi không thể giải thích cảnh báo. Nó nói gì? Là tập tin của tôi thực sự ngẫu nhiên sau khi cảnh báo hoặc có vấn đề? +0 hoặc +1 trong 800950+1 Datensätze ein800950+0 Datensätze auscó nghĩa là gì? Sau khi cảnh báo, nó là +1. Có phải là một lỗi?


Điều này sẽ dễ trả lời hơn nếu bạn có thể dịch các tin nhắn sang tiếng Anh. Ngoài ra, định nghĩa "thực sự ngẫu nhiên". Mức độ ngẫu nhiên nào bạn yêu cầu, bạn sẽ sử dụng nó để làm gì?
terdon

Để nhận tin nhắn tiếng Anh, hãy sử dụng LC_ALL=Ctrước lệnh, nhưLC_ALL=C dd if=...
Volker Siegel

Câu trả lời:


38

Tóm tắt: ddlà một công cụ cáu kỉnh, khó sử dụng chính xác. Đừng sử dụng nó, mặc dù có rất nhiều hướng dẫn cho bạn biết như vậy. ddcó một điểm đáng tin cậy trên đường phố của người Anh gắn liền với nó - nhưng nếu bạn thực sự hiểu những gì bạn đang làm, bạn sẽ biết rằng bạn không nên chạm vào nó với một cột 10 feet.

ddthực hiện một cuộc gọi đến cuộc gọi readhệ thống trên mỗi khối (được xác định bởi giá trị của bs). Không có gì đảm bảo rằng readcuộc gọi hệ thống trả về nhiều dữ liệu như kích thước bộ đệm đã chỉ định. Điều này có xu hướng hoạt động cho các tệp thông thường và các thiết bị chặn, nhưng không phải cho các đường ống và một số thiết bị ký tự. Xem Khi nào dd phù hợp để sao chép dữ liệu? (hoặc, khi được đọc () và viết () một phần) để biết thêm thông tin. Nếu readcuộc gọi hệ thống trả về ít hơn một khối đầy đủ, sau đó ddchuyển một phần khối. Nó vẫn sao chép số lượng khối được chỉ định, do đó tổng số byte được truyền ít hơn yêu cầu.

Cảnh báo về việc đọc một phần của người Viking cho bạn biết chính xác điều này: một trong những lần đọc là một phần, do đó đã ddchuyển một khối không hoàn chỉnh. Trong số đếm khối, +1có nghĩa là một khối đã được đọc một phần; vì số lượng đầu ra là +0, tất cả các khối được viết ra là đã đọc.

Điều này không ảnh hưởng đến tính ngẫu nhiên của dữ liệu: tất cả các byte ddghi ra là các byte mà nó đọc từ đó /dev/urandom. Nhưng bạn có ít byte hơn dự kiến.

Linux cung /dev/urandomcấp các yêu cầu lớn tùy ý (nguồn: extract_entropy_userin drivers/char/random.c), do đó ddthường an toàn khi đọc từ nó. Tuy nhiên, đọc số lượng lớn dữ liệu cần có thời gian. Nếu quá trình nhận được tín hiệu, readcuộc gọi hệ thống trả về trước khi điền vào bộ đệm đầu ra của nó. Đây là hành vi bình thường và các ứng dụng được yêu cầu gọi readtheo vòng lặp; ddkhông làm điều này, vì lý do lịch sử ( ddnguồn gốc là âm u, nhưng dường như nó đã bắt đầu như một công cụ để truy cập băng, có yêu cầu đặc biệt, và không bao giờ được điều chỉnh thành một công cụ đa năng). Khi bạn kiểm tra tiến trình, điều này sẽ gửi ddquá trình tín hiệu làm gián đoạn việc đọc. Bạn có một sự lựa chọn giữa việc biết có bao nhiêu byteddsẽ sao chép toàn bộ (đảm bảo không làm gián đoạn nó - không kiểm tra tiến trình, không đình chỉ) hoặc biết có bao nhiêu byte ddđã được sao chép cho đến nay, trong trường hợp đó bạn không thể biết mình sẽ sao chép thêm bao nhiêu byte.

Phiên bản ddtrong lõi core GNU (như được tìm thấy trên Linux không được nhúng và trên Cygwin) có một cờ fullblockcho biết ddđể gọi readtrong một vòng lặp (và ditto cho write) và do đó luôn chuyển các khối đầy đủ. Thông báo lỗi cho thấy bạn sử dụng nó; bạn nên luôn luôn sử dụng nó (trong cả cờ đầu vào và đầu ra), ngoại trừ trong những trường hợp rất đặc biệt (chủ yếu là khi truy cập băng) - nếu bạn sử dụng ddtất cả, đó là: thường có giải pháp tốt hơn (xem bên dưới).

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

Một cách khác có thể để chắc chắn về những gì ddsẽ làm là vượt qua kích thước khối 1. Sau đó, bạn có thể cho biết có bao nhiêu byte đã được sao chép từ số khối, mặc dù tôi không chắc điều gì sẽ xảy ra nếu readbị gián đoạn trước khi đọc lần đầu tiên byte (không có nhiều khả năng trong thực tế nhưng có thể xảy ra). Tuy nhiên, ngay cả khi nó hoạt động, điều này rất chậm.

Lời khuyên chung về việc sử dụng ddkhông sử dụngdd . Mặc dù ddthường được quảng cáo là một lệnh cấp thấp để truy cập các thiết bị, nhưng thực tế không phải vậy: tất cả các phép thuật xảy ra trong phần (tệp /dev/…) của thiết bị , ddchỉ là một công cụ thông thường có khả năng lạm dụng cao dẫn đến mất dữ liệu . Trong hầu hết các trường hợp, có một cách đơn giản và an toàn hơn để làm những gì bạn muốn, ít nhất là trên Linux.

Ví dụ, để đọc một số byte nhất định ở đầu tệp, chỉ cần gọi head:

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

Tôi đã tạo một điểm chuẩn nhanh trên máy của mình và không quan sát thấy bất kỳ sự khác biệt hiệu suất nào giữa ddkích thước khối lớn và head.

Nếu bạn cần bỏ qua một số byte lúc đầu, hãy tailchuyển sang head:

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

Nếu bạn muốn xem tiến trình, hãy gọi lsofđể xem tập tin bù. Điều này chỉ hoạt động trên một tệp thông thường (tệp đầu ra trên ví dụ của bạn), không phải trên một thiết bị ký tự.

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

Bạn có thể gọi pvđể nhận báo cáo tiến độ (tốt hơn so với dd), với chi phí của một mục bổ sung trong đường ống (thông minh về hiệu suất, hầu như không nhận thấy được).


2
+1. Đây là một trong những bài viết được nghiên cứu kỹ lưỡng nhất mà tôi đã đọc trên mạng StackExchange trong một thời gian dài. Nó ngắn gọn nhưng chứa tất cả các chi tiết (lịch sử và ngày nay) về ddmệnh lệnh mà tôi không nhận ra mình cần biết. Cảm ơn.
Ossifrage vũ trụ ngày 7/10/2015

4
Tôi xin lỗi nhưng tôi không đồng ý với khẳng định của bạn rằng dd là một "công cụ cáu kỉnh khó sử dụng chính xác" và "không sử dụng dd". Nó là một tiện ích hoàn toàn tốt khi được sử dụng một cách chính xác bởi ai đó đã dành thời gian để hiểu nó. Thật vậy, bộ công cụ pháp y đĩa hầu như tất cả phụ thuộc vào dd hoặc một dẫn xuất như dcfldd.
fpmurphy

1
@ fpmurphy1 GNU ddcó thể được sử dụng một cách an toàn, nhờ vào fullblocktùy chọn của nó . Nhưng nếu bạn có GNU coreutils, bạn không cần ddnhiều. “Phái sinh” như dcflddđược không dd , họ không bị lỗi thiết kế của nó, vì vậy câu trả lời của tôi không áp dụng đối với họ. Phần lớn, đại đa số những người sử dụng ddđã không dành đủ thời gian để hiểu về nó (nhiều nhất, họ đã dành thời gian để nghĩ rằng họ hiểu nó) và cách họ sử dụng nó dẫn đến mất dữ liệu.
Gilles 'SO- ngừng trở nên xấu xa'

1
@Gilles Vì vậy, chúng ta không nên sử dụng "echo" b / c về khả năng sử dụng sai (sudo echo hello world> / dev / sda)?
Whitey04

2
@ whitey04 Tôi khuyên bạn không nên xử lý thùng nitroglycerine. Tôi không nói rằng bạn không nên sử dụng diêm.
Gilles 'SO- ngừng trở nên xấu xa'

9

Cảnh báo xảy ra khi ddkhông thể có đủ dữ liệu để điền vào một khối trong một lần đọc. Điều này xảy ra với các nguồn dữ liệu thất thường hoặc chậm hoặc các nguồn ghi dữ liệu theo các đơn vị nhỏ hơn kích thước khối yêu cầu của bạn.

Không có vấn đề với tính toàn vẹn dữ liệu, nhưng vấn đề là ddtính một phần đọc vẫn là một khối đọc.

Nếu bạn không sử dụng counttùy chọn, cảnh báo hầu như không quan trọng, đó chỉ là một sự cân nhắc về hiệu suất. Nhưng với count, bạn sẽ không nhận được lượng dữ liệu bạn yêu cầu. Do đọc một phần, ofsẽ nhỏ hơn count*bsở cuối.

Vì vậy, khi bạn sử dụng count, về mặt kỹ thuật bạn cũng nên luôn luôn sử dụng iflag=fullblock.

Các +xnên là số khối một phần.


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

^ Điều đó sẽ làm việc. Thông tin sai lệch có ở đây rõ ràng là sai. ddBộ đệm là rõ ràng và do đó, để đệm đầu vào để đếm số lần xuất hiện, bạn cần phải đệm rõ ràng. Đó là tất cả. Đừng mua fud.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.