ขีด จำกัด อักขระบรรทัดคำสั่ง Linux


27

ฉันส่งตัวแปรไปยังสคริปต์ในบรรทัดคำสั่ง ขีด จำกัด อักขระของคำสั่งคืออะไร เช่น:

$ MyScript reallyreallyreally...reallyreallyreallylongoption

ขอบคุณ


1
ฉันไม่เข้าใจคำถาม. คุณสนใจที่จะ จำกัด ตัวละครหรือไม่?
krissi

คุณต้องระบุคำถามของคุณให้ชัดเจนยิ่งขึ้นมิฉะนั้นจะเป็นการปิดตัวลง
ThatGraemeGuy

คำตอบ:


26

โดยทั่วไปแล้วขีด จำกัด ที่กำหนดของเชลล์ / OS นั้นยาวมากโดยทั่วไปคือหนึ่งหรือสองพันตัวอักษร

getconf ARG_MAXจะให้ขีด จำกัด อินพุตสูงสุดสำหรับคำสั่ง ในระบบ Debian ปัจจุบันฉันมีเทอร์มินัลเปิดอยู่ซึ่งจะคืนค่า 131072 ซึ่งเป็น 128 * 1024 ขีด จำกัด จะลดลงโดยตัวแปรสภาพแวดล้อมของคุณราวกับว่าหน่วยความจำของฉันให้บริการฉันอย่างถูกต้องสิ่งเหล่านี้จะถูกส่งผ่านในโครงสร้างเดียวกันโดยเชลล์แม้ว่ามันจะใช้เวลาเพียงไม่กี่ร้อยตัวอักษรในกรณีส่วนใหญ่ เพื่อหาค่าประมาณของการรันค่านี้env | wc -c- ซึ่งจะแนะนำ 325 ตัวอักษร ณ เวลาปัจจุบันของข้อมูลล็อกอินนี้บนเครื่องนี้

สคริปต์มีแนวโน้มที่จะอนุญาตให้ใช้ความยาวเต็มรูปแบบนี้ แต่ไม่น่าเป็นไปได้ที่ยูทิลิตี้อื่น ๆ จะกำหนดขีด จำกัด ของตัวเองไม่ว่าจะโดยเจตนาหรือผ่านปัญหาการออกแบบ นอกจากนี้ยังอาจมีข้อ จำกัด ในการประดิษฐ์ว่าอาร์กิวเมนต์แต่ละตัวบนบรรทัดคำสั่งยาวสามารถเป็นเท่าใดและ / หรือระยะเวลาที่พา ธ ไปยังไฟล์นานเท่าใด


2
ในระบบของฉันgetconf ARG_MAXให้ 2097152 แต่ความยาวสูงสุดที่ฉันสามารถผ่านได้คือ 131071 (และฉันไม่ต้องหักขนาดของสภาพแวดล้อม)
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

1
ยังจำได้ว่าxargsและแม้กระทั่งfind -execเป็นเพื่อนของคุณเมื่อจัดการกับรายการอาร์กิวเมนต์ยักษ์
coredump

@Dennis: ค่าที่ส่งคืนโดยgetconfเป็นระดับเคอร์เนลฉันคิดว่า บางทีทุบตีกำลังตั้งค่าขีด จำกัด ล่างด้วยการออกแบบ / การกำหนดค่า? นอกจากนี้ความรู้ของฉันเกี่ยวกับเรื่องนี้มาจากเมื่อไม่นานมานี้ดังนั้นอาจเป็นไปได้ว่าสิ่งต่าง ๆ เปลี่ยนไปเล็กน้อยเมื่อเร็ว ๆ นี้แม้ว่ามันจะไม่ใช่พื้นที่ที่ฉันคาดว่าจะเห็นการเคลื่อนไหวจำนวนมากยกเว้นในเปลือกทดลองใหม่
David Spillett

ฉันได้รับผลลัพธ์เดียวกันในksh, zsh, dash, fishและทุบตี 3 เท่าที่ฉันทำในทุบตี 4. เกิดข้อผิดพลาดจากการfishอาจจะให้ข้อมูล: "ปลา: ขนาดรวมของการโต้แย้งและสภาพแวดล้อมในรายการ (130kB) เกินขีด จำกัด ระบบปฏิบัติการของ 2.0MB ." อย่างไรก็ตามset | wc -cคือ 306317 และenv | wc -c2507 ซึ่งไม่ได้คำนึงถึงความแตกต่าง ฉันไม่รู้ว่ากำลังนับอะไรอีก
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

10

ARG_MAX จำกัด ขนาดโดยรวมของบรรทัดคำสั่งและสภาพแวดล้อมอย่างแน่นอน แต่คุณกำลังเผชิญกับข้อ จำกัด เพิ่มเติม: หนึ่งอาร์กิวเมนต์ต้องไม่เกิน MAX_ARG_STRLEN (ซึ่งเป็นรหัสยากที่จะ 131072)

ดู/unix/120642/what-defines-the-maximum-size-for-a-command-single-argument


1

คุณหมายถึงความยาวของตัวแปรที่ยาวที่สุดคืออะไร? เพื่อหาว่าคุณสามารถใช้ "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


3
นอกจากนี้คุณไม่จำเป็นต้องใช้perlและสคริปต์:/bin/echo "$(printf "%*s" 131071 ".")">/dev/null
หยุดชั่วคราวจนกว่าจะมีประกาศ

@DennisWilliamson printf '%s\n' "$(printf '%*s' 131072 .)" >/dev/nullทำงานอย่างไร
jarno

นั่นเป็นเพราะprintfเชลล์ในตัวจึงbashไม่จำเป็นต้องทำexec()เพื่อวางไข่กระบวนการอื่น ARG_MAXเพียง แต่มีความสำคัญกับความยาวของรายการอาร์กิวเมนต์ของexecฟังก์ชั่น ( exec(), execl(), execlp(), execvp(), execvpe()ฯลฯ )
Vicente Olivert Riera
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.