พิจารณาว่ามีไฟล์นับไม่ถ้วนภายใต้ / src /
cp /src/* /dst/
cpสามารถประมวลผลไฟล์ได้สำเร็จกี่ไฟล์?
พิจารณาว่ามีไฟล์นับไม่ถ้วนภายใต้ / src /
cp /src/* /dst/
cpสามารถประมวลผลไฟล์ได้สำเร็จกี่ไฟล์?
คำตอบ:
ขึ้นอยู่กับระบบและเวอร์ชันเป็นอย่างมากตามจำนวนและขนาดของอาร์กิวเมนต์และจำนวนและขนาดของชื่อตัวแปรสภาพแวดล้อม
ตามธรรมเนียมบน Unix ขีด จำกัด (ตามที่รายงานโดยgetconf ARG_MAX) มีขนาดเพิ่มขึ้นหรือน้อยลงตาม:
'\0')'\0') var=valueสตริงสภาพแวดล้อมที่เป็นอะไรบางอย่างเช่นการประชุมจำไว้ว่าcpยังนับเป็นอาร์กิวเมนต์ (เป็นอาร์กิวเมนต์แรก)
บน Linux มันขึ้นอยู่กับเวอร์ชั่น พฤติกรรมที่มีการเปลี่ยนแปลงเมื่อเร็ว ๆ นี้ที่มันไม่ได้เป็นพื้นที่คงที่อีกต่อไป
ตรวจสอบบน Linux 3.11 getconf ARG_MAXตอนนี้รายงานหนึ่งในสี่ของขีด จำกัด ที่ตั้งค่าไว้กับขนาดสแต็กหรือ 128kiB หากน้อยกว่า 512kiB)
( zshไวยากรณ์ด้านล่าง):
$ limit stacksize
stacksize 8MB
$ getconf ARG_MAX
2097152
$ limit stacksize 4M
$ getconf ARG_MAX
1048576
ขีด จำกัด นั้นขึ้นอยู่กับขนาดสะสมของอาร์กิวเมนต์และสตริงสภาพแวดล้อมและค่าใช้จ่ายบางส่วน (ฉันสงสัยว่าเนื่องจากการพิจารณาการจัดตำแหน่งในขอบเขตหน้า) ขนาดของพอยน์เตอร์ไม่ได้ถูกนำมาพิจารณา
ค้นหาขีด จำกัด ฉันได้รับ:
$ /bin/true {1..164686}
$ /bin/true {1..164687}
zsh: argument list too long: /bin/true
$ x= /bin/true {1..164686}
$ x=1 /bin/true {1..164686}
zsh: argument list too long: /bin/true
ขนาดสะสมสูงสุดก่อนแตกในกรณีนี้คือ:
$ (env _=/bin/true x=;print -l /bin/true {1..164686}) | wc -c
1044462
ตอนนี้ไม่ได้หมายความว่าคุณสามารถผ่านอาร์กิวเมนต์ที่ว่าง 1 ล้าน บนระบบ 64 บิตอาร์กิวเมนต์ว่างเปล่า 1 ล้านรายการสร้างรายการตัวชี้ขนาด 8MB ซึ่งจะสูงกว่าขนาดสแต็กของฉันที่ 4MiB
$ IFS=:; /bin/true ${=${(l.1000000..:.)${:-}}}
zsh: killed /bin/true ${=${(l.1000000..:.)${:-}}}
(คุณจะสังเกตเห็นว่าไม่ใช่ข้อผิดพลาด E2BIG ฉันไม่แน่ใจว่าจะมีกระบวนการใดถูกฆ่าที่จุดนั้นแม้ว่าจะอยู่ในการexecveเรียกของระบบหรือหลังจากนั้น)
โปรดทราบว่า (ยังคงอยู่บน Linux 3.11) ว่าขนาดสูงสุดของอาร์กิวเมนต์เดียวหรือสตริงสภาพแวดล้อมคือ 128kiB โดยไม่คำนึงถึงขนาดสแต็ก
$ /bin/true ${(l.131071..a.)${:-}} # 131072 OK
$ /bin/true ${(l.131072..a.)${:-}} # 131073 not
zsh: argument list too long: /bin/true
$ /bin/true ${(l.131071..a.)${:-}} ${(l.131071..a.)${:-}} # 2x 131072 OK
164686เลขอย่างไร นั่นคือวิธีที่คุณคำนวณลำดับที่จะอยู่ภายใต้2097152ขนาด ARG_MAX?
ที่จะขึ้นอยู่กับค่าของ ARG_MAX ซึ่งสามารถเปลี่ยนระหว่างระบบ หากต้องการทราบค่าสำหรับการทำงานของระบบของคุณ (แสดงผลการขุดเป็นตัวอย่าง):
$ getconf ARG_MAX
2097152
นี้มีอะไรจะทำอย่างไรกับcpหรือเปลือกของคุณมันเป็นข้อ จำกัด ที่กำหนดโดยเคอร์เนลก็จะไม่ดำเนินการ ( exec()) ARG_MAXคำสั่งถ้าขัดแย้งของพวกเขามีความยาวมากกว่า ดังนั้นหากความยาวของรายการอาร์กิวเมนต์ที่คุณให้cpมากกว่า ARG_MAX cpคำสั่งจะไม่ทำงานเลย
เพื่อตอบคำถามหลักของคุณแล้วcpจะไม่ประมวลผลไฟล์ใด ๆ เนื่องจากจะไม่มีการดำเนินการกับอาร์กิวเมนต์จำนวนมาก ฉันควรพูดถึงว่าสิ่งนี้ไม่ได้ขึ้นอยู่กับจำนวนอาร์กิวเมนต์ แต่ขึ้นอยู่กับความยาว คุณอาจมีปัญหาเดียวกันกับชื่อไฟล์น้อยมาก แต่ยาวมาก
วิธีการแก้ไขข้อผิดพลาดเหล่านี้คือการเรียกใช้คำสั่งของคุณแบบวนซ้ำ:
for file in /src/*; do cp "$file" /dst/; done
Cสามารถมีปัญหากับ ARG_MAX และชื่อไฟล์ที่ยาวมาก ๆ ?
IFS="\n" for file in /src/*; do mv "$file" /dst/; donersync -a /src/ /dst/