พิจารณาว่ามีไฟล์นับไม่ถ้วนภายใต้ / 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/; done
rsync -a /src/ /dst/