Tôi có ấn tượng rằng độ dài tối đa của một đối số không phải là vấn đề ở đây nhiều như tổng kích thước của mảng đối số tổng thể cộng với kích thước của môi trường, được giới hạn ARG_MAX. Vì vậy, tôi nghĩ rằng một cái gì đó như sau sẽ thành công:
env_size=$(cat /proc/$$/environ | wc -c)
(( arg_size = $(getconf ARG_MAX) - $env_size - 100 ))
/bin/echo $(tr -dc [:alnum:] </dev/urandom | head -c $arg_size) >/dev/null
Với sự - 100tồn tại quá đủ để tính đến sự khác biệt giữa kích thước của môi trường trong vỏ và echoquy trình. Thay vào đó tôi đã nhận được lỗi:
bash: /bin/echo: Argument list too long
Sau khi chơi một lúc, tôi thấy rằng mức tối đa là một thứ tự hex có độ lớn nhỏ hơn:
/bin/echo \
$(tr -dc [:alnum:] </dev/urandom | head -c $(($(getconf ARG_MAX)/16-1))) \
>/dev/null
Khi trừ đi một cái, lỗi sẽ trả về. Dường như mức tối đa cho một đối số là thực sự ARG_MAX/16và các -1tài khoản cho byte null được đặt ở cuối chuỗi trong mảng đối số.
Một vấn đề khác là khi đối số được lặp lại, tổng kích thước của mảng đối số có thể gần hơn ARG_MAX, nhưng vẫn không hoàn toàn ở đó:
args=( $(tr -dc [:alnum:] </dev/urandom | head -c $(($(getconf ARG_MAX)/16-1))) )
for x in {1..14}; do
args+=( ${args[0]} )
done
/bin/echo "${args[@]}" "${args[0]:6534}" >/dev/null
Sử dụng "${args[0]:6533}"ở đây làm cho đối số cuối cùng dài hơn 1 byte và đưa ra Argument list too longlỗi. Sự khác biệt này khó có thể được tính bằng kích thước của môi trường được đưa ra:
$ cat /proc/$$/environ | wc -c
1045
Câu hỏi:
- Đây có phải là hành vi chính xác, hoặc có một lỗi ở đâu đó?
- Nếu không, hành vi này được ghi nhận ở bất cứ đâu? Có một tham số khác xác định mức tối đa cho một đối số không?
- Là hành vi này giới hạn trong Linux (hoặc thậm chí các phiên bản cụ thể như vậy)?
- Điều gì chiếm sự khác biệt ~ 5KB bổ sung giữa kích thước tối đa thực tế của mảng đối số cộng với kích thước gần đúng của môi trường và
ARG_MAX?
Thông tin bổ sung:
uname -a
Linux graeme-rock 3.13-1-amd64 #1 SMP Debian 3.13.5-1 (2014-03-04) x86_64 GNU/Linux
getconf ARG_MAXphụ thuộc vào hiện tại ulimit -s. Đặt nó thành không giới hạn và nhận được 4611686018427387903 tuyệt vời cho ARG_MAX.