Saya mendapat kesan bahwa panjang maksimum satu argumen tidak menjadi masalah di sini sebanyak ukuran total array argumen keseluruhan plus ukuran lingkungan, yang terbatas pada ARG_MAX
. Jadi saya pikir sesuatu seperti yang berikut ini akan berhasil:
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
Dengan - 100
menjadi lebih dari cukup untuk menjelaskan perbedaan antara ukuran lingkungan di shell dan echo
prosesnya. Sebaliknya saya mendapat kesalahan:
bash: /bin/echo: Argument list too long
Setelah bermain-main sebentar, saya menemukan bahwa maksimum adalah urutan hex besarnya lebih kecil:
/bin/echo \
$(tr -dc [:alnum:] </dev/urandom | head -c $(($(getconf ARG_MAX)/16-1))) \
>/dev/null
Ketika yang minus dihapus, kesalahan kembali. Tampaknya maksimum untuk argumen tunggal sebenarnya ARG_MAX/16
dan -1
akun untuk byte nol ditempatkan di akhir string dalam array argumen.
Masalah lain adalah ketika argumen diulangi, ukuran total array argumen bisa lebih dekat ARG_MAX
, tetapi masih belum cukup:
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
Menggunakan di "${args[0]:6533}"
sini membuat argumen terakhir 1 byte lebih lama dan memberikan Argument list too long
kesalahan. Perbedaan ini tidak mungkin diperhitungkan oleh ukuran lingkungan yang diberikan:
$ cat /proc/$$/environ | wc -c
1045
Pertanyaan:
- Apakah ini perilaku yang benar, atau ada bug di suatu tempat?
- Jika tidak, apakah perilaku ini didokumentasikan di mana saja? Apakah ada parameter lain yang menentukan maksimum untuk satu argumen?
- Apakah perilaku ini terbatas pada Linux (atau bahkan versi tertentu)?
- Apa yang menyebabkan perbedaan tambahan ~ 5KB antara ukuran maksimum sebenarnya dari argumen array ditambah ukuran perkiraan lingkungan dan
ARG_MAX
?
Informasi tambahan:
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_MAX
tergantung pada saat ini ulimit -s
. Setel ke tak terbatas, dan dapatkan 4611686018427387903 yang luar biasa untuk ARG_MAX.