ARG_MAX
ฉันถูกภายใต้การแสดงผลที่ความยาวสูงสุดของอาร์กิวเมนต์เดียวไม่ได้เป็นปัญหาที่นี่ให้มากที่สุดเท่าขนาดรวมของอาร์กิวเมนต์อาร์เรย์โดยรวมขนาดบวกของสภาพแวดล้อมซึ่งจะถูก จำกัด ดังนั้นฉันคิดว่าบางสิ่งเช่นนี้จะประสบความสำเร็จ:
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
ด้วยความ- 100
ที่เกินพอที่จะอธิบายความแตกต่างระหว่างขนาดของสภาพแวดล้อมในเชลล์และecho
กระบวนการ แต่ฉันได้รับข้อผิดพลาด:
bash: /bin/echo: Argument list too long
หลังจากเล่นไปซักพักผมก็พบว่าค่าสูงสุดนั้นเป็นลำดับเลขฐานสิบหกที่เล็กกว่า:
/bin/echo \
$(tr -dc [:alnum:] </dev/urandom | head -c $(($(getconf ARG_MAX)/16-1))) \
>/dev/null
เมื่อลบหนึ่งลบข้อผิดพลาดจะกลับมา ดูเหมือนว่าค่าสูงสุดสำหรับอาร์กิวเมนต์เดียวนั้นแท้จริงแล้วARG_MAX/16
และ-1
บัญชีสำหรับไบต์ว่างที่ท้ายของสตริงในอาร์เรย์อาร์กิวเมนต์
ปัญหาอีกข้อคือเมื่ออาร์กิวเมนต์เกิดขึ้นซ้ำขนาดรวมของอาเรย์จะใกล้เคียงARG_MAX
กัน แต่ก็ยังไม่ถึงเท่านี้
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
การใช้"${args[0]:6533}"
ที่นี่จะทำให้อาร์กิวเมนต์สุดท้าย 1 ไบต์ยาวขึ้นและทำให้เกิดArgument list too long
ข้อผิดพลาด ความแตกต่างนี้ไม่น่าจะนำมาพิจารณาโดยขนาดของสภาพแวดล้อมที่กำหนด:
$ cat /proc/$$/environ | wc -c
1045
คำถาม:
- นี่เป็นพฤติกรรมที่ถูกต้องหรือมีข้อผิดพลาดอยู่ที่ไหนสักแห่ง?
- ถ้าไม่พฤติกรรมนี้มีการบันทึกไว้ทุกที่หรือไม่? มีพารามิเตอร์อื่นที่กำหนดค่าสูงสุดสำหรับอาร์กิวเมนต์เดียวหรือไม่
- พฤติกรรมนี้ จำกัด เฉพาะ Linux (หรือเฉพาะบางรุ่น)
- บัญชีอะไรเพิ่มเติมความแตกต่างระหว่าง ~ 5KB ขนาดสูงสุดที่เกิดขึ้นจริงของอาร์เรย์อาร์กิวเมนต์บวกประมาณขนาดของสภาพแวดล้อมและ
ARG_MAX
?
ข้อมูลเพิ่มเติม:
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
ulimit -s
กำหนดเป็นไม่ จำกัด และรับ 4611686018427387903 สำหรับ ARG_MAX ที่น่าทึ่ง