ฉันส่งตัวแปรไปยังสคริปต์ในบรรทัดคำสั่ง ขีด จำกัด อักขระของคำสั่งคืออะไร เช่น:
$ MyScript reallyreallyreally...reallyreallyreallylongoption
ขอบคุณ
ฉันส่งตัวแปรไปยังสคริปต์ในบรรทัดคำสั่ง ขีด จำกัด อักขระของคำสั่งคืออะไร เช่น:
$ MyScript reallyreallyreally...reallyreallyreallylongoption
ขอบคุณ
คำตอบ:
โดยทั่วไปแล้วขีด จำกัด ที่กำหนดของเชลล์ / OS นั้นยาวมากโดยทั่วไปคือหนึ่งหรือสองพันตัวอักษร
getconf ARG_MAX
จะให้ขีด จำกัด อินพุตสูงสุดสำหรับคำสั่ง ในระบบ Debian ปัจจุบันฉันมีเทอร์มินัลเปิดอยู่ซึ่งจะคืนค่า 131072 ซึ่งเป็น 128 * 1024 ขีด จำกัด จะลดลงโดยตัวแปรสภาพแวดล้อมของคุณราวกับว่าหน่วยความจำของฉันให้บริการฉันอย่างถูกต้องสิ่งเหล่านี้จะถูกส่งผ่านในโครงสร้างเดียวกันโดยเชลล์แม้ว่ามันจะใช้เวลาเพียงไม่กี่ร้อยตัวอักษรในกรณีส่วนใหญ่ เพื่อหาค่าประมาณของการรันค่านี้env | wc -c
- ซึ่งจะแนะนำ 325 ตัวอักษร ณ เวลาปัจจุบันของข้อมูลล็อกอินนี้บนเครื่องนี้
สคริปต์มีแนวโน้มที่จะอนุญาตให้ใช้ความยาวเต็มรูปแบบนี้ แต่ไม่น่าเป็นไปได้ที่ยูทิลิตี้อื่น ๆ จะกำหนดขีด จำกัด ของตัวเองไม่ว่าจะโดยเจตนาหรือผ่านปัญหาการออกแบบ นอกจากนี้ยังอาจมีข้อ จำกัด ในการประดิษฐ์ว่าอาร์กิวเมนต์แต่ละตัวบนบรรทัดคำสั่งยาวสามารถเป็นเท่าใดและ / หรือระยะเวลาที่พา ธ ไปยังไฟล์นานเท่าใด
getconf ARG_MAX
ให้ 2097152 แต่ความยาวสูงสุดที่ฉันสามารถผ่านได้คือ 131071 (และฉันไม่ต้องหักขนาดของสภาพแวดล้อม)
xargs
และแม้กระทั่งfind -exec
เป็นเพื่อนของคุณเมื่อจัดการกับรายการอาร์กิวเมนต์ยักษ์
getconf
เป็นระดับเคอร์เนลฉันคิดว่า บางทีทุบตีกำลังตั้งค่าขีด จำกัด ล่างด้วยการออกแบบ / การกำหนดค่า? นอกจากนี้ความรู้ของฉันเกี่ยวกับเรื่องนี้มาจากเมื่อไม่นานมานี้ดังนั้นอาจเป็นไปได้ว่าสิ่งต่าง ๆ เปลี่ยนไปเล็กน้อยเมื่อเร็ว ๆ นี้แม้ว่ามันจะไม่ใช่พื้นที่ที่ฉันคาดว่าจะเห็นการเคลื่อนไหวจำนวนมากยกเว้นในเปลือกทดลองใหม่
ksh
, zsh
, dash
, fish
และทุบตี 3 เท่าที่ฉันทำในทุบตี 4. เกิดข้อผิดพลาดจากการfish
อาจจะให้ข้อมูล: "ปลา: ขนาดรวมของการโต้แย้งและสภาพแวดล้อมในรายการ (130kB) เกินขีด จำกัด ระบบปฏิบัติการของ 2.0MB ." อย่างไรก็ตามset | wc -c
คือ 306317 และenv | wc -c
2507 ซึ่งไม่ได้คำนึงถึงความแตกต่าง ฉันไม่รู้ว่ากำลังนับอะไรอีก
ARG_MAX จำกัด ขนาดโดยรวมของบรรทัดคำสั่งและสภาพแวดล้อมอย่างแน่นอน แต่คุณกำลังเผชิญกับข้อ จำกัด เพิ่มเติม: หนึ่งอาร์กิวเมนต์ต้องไม่เกิน MAX_ARG_STRLEN (ซึ่งเป็นรหัสยากที่จะ 131072)
ดู/unix/120642/what-defines-the-maximum-size-for-a-command-single-argument
คุณหมายถึงความยาวของตัวแปรที่ยาวที่สุดคืออะไร? เพื่อหาว่าคุณสามารถใช้ "x" ของ perl เพื่อสร้างชื่อตัวแปรที่ยาวมาก:
VAR=`perl -e 'print "a"x131071'` ; bash a.sh $VAR
ในระบบ My 131071 ใช้งานได้:
และตัวแปรถูกพิมพ์ที่ 131072 มันใหญ่เกินไป:
VAR=`perl -e 'print "a"x131072'` ; bash a.sh $VAR
bash: /bin/bash: Argument list too long
perl
และสคริปต์:/bin/echo "$(printf "%*s" 131071 ".")">/dev/null
printf '%s\n' "$(printf '%*s' 131072 .)" >/dev/null
ทำงานอย่างไร
printf
เชลล์ในตัวจึงbash
ไม่จำเป็นต้องทำexec()
เพื่อวางไข่กระบวนการอื่น ARG_MAX
เพียง แต่มีความสำคัญกับความยาวของรายการอาร์กิวเมนต์ของexec
ฟังก์ชั่น ( exec()
, execl()
, execlp()
, execvp()
, execvpe()
ฯลฯ )