Dd
dd 的 bs 參數的最大值是多少?
我想寫一個 CGI,它必須從 STDIN 讀取指定數量的字節。我的想法是這樣做:
dd bs=$CONTENT_LENGTH count=1
但我想知道,塊大小是否受 RAM 以外的任何限制。
$ dd bs=1000000000000 dd: memory exhausted by input buffer of size 1000000000000 bytes (931 GiB)
GNU 的 coreutils 的手冊頁沒有指定任何限制。
POSIX 規範
dd
沒有明確指定最大值,但有一些限制:
- 用於儲存給定值的數據類型可以預期為,因為這是給定函式
size_t
要讀取的字節數的類型;read
read
還指定有一個限制SSIZE_MAX
;- 在 Linux 下,無論如何
read
只能傳輸 2,147,479,552 字節。在 64 位平台上,
size_t
長度為 64 位;此外,它是無符號的,因此dd
當給定值大於 2 64 – 1 時會失敗:$ dd if=/dev/zero of=/dev/null bs=18446744073709551616 dd: invalid number: ‘18446744073709551616’
在 64 位 x86 上的 Linux 上,
SSIZE_MAX
是 0x7fffffffffffffffL(執行echo SSIZE_MAX | gcc -include limits.h -E -
檢查),這就是輸入限制:$ dd if=/dev/zero of=/dev/null bs=9223372036854775808 dd: invalid number: ‘9223372036854775808’: Value too large for defined data type $ dd if=/dev/zero of=/dev/null bs=9223372036854775807 dd: memory exhausted by input buffer of size 9223372036854775807 bytes (8.0 EiB)
一旦找到一個可以接受的值,下一個限制就是可以分配的記憶體量,因為
dd
需要先分配一個緩衝區,然後才能讀入它。一旦找到可以分配的值,您將達到
read
限制(在 Linux 和其他具有類似限制的系統上),除非您使用 GNUdd
並指定iflag=fullblock
:$ dd if=/dev/zero of=ddtest bs=4294967296 count=1 0+1 records in 0+1 records out 2147479552 bytes (2.1 GB, 2.0 GiB) copied, 38.3037 s, 56.1 MB/s
(
dd
複製不到 2 31個字節,即上面提到的 Linux 限制,甚至不到我要求的一半)。正如上面連結的問答中所解釋的,
fullblock
在任何情況下,對於任何bs
大於 1 的值,您都需要可靠地複制所有輸入數據。