CP: अधिकतम स्रोत फ़ाइलों की प्रतिलिपि उपयोगिता के लिए संख्या तर्क


11

गौर करें कि अनगिनत संख्या में / src / के तहत फाइलें हैं

cp /src/* /dst/

कितनी फाइलें cpसफलतापूर्वक संसाधित होंगी?


2
यदि तर्क सूची बहुत लंबी है (याद रखें, जो * करता है वह सभी फ़ाइलों की एक सूची का विस्तार होता है जो ग्लोब से मेल खाती है), आप इसे उदाहरण के लिए IFS="\n" for file in /src/*; do mv "$file" /dst/; doneया इसके उपयोग से प्राप्त कर सकते हैं rsync -a /src/ /dst/
डोपघोटी

जवाबों:


18

यह प्रणाली और संस्करण पर, तर्कों की संख्या और आकार और पर्यावरण चर नामों की संख्या और आकार पर बहुत निर्भर करता है।

परंपरागत रूप से यूनिक्स पर, सीमा (जैसा कि बताया गया है getconf ARG_MAX) कमोबेश आकार में थी:

  • तर्क तार की लंबाई (समाप्ति सहित '\0')
  • उन तारों को इंगित करने वाले सरणी की लंबाई, इसलिए 64 बिट सिस्टम पर आमतौर पर 8 बाइट प्रति तर्क
  • पर्यावरण तार की लंबाई (समापन सहित '\0'), एक पर्यावरण स्ट्रिंग जैसे कि सम्मेलन द्वारा किया जा रहा है var=value
  • उन तारों को इंगित करने वाले सरणी की लंबाई, इसलिए 64 बिट सिस्टम पर आमतौर पर 8 बाइट प्रति तर्क

ध्यान में रखते हुए कि cpएक तर्क के रूप में भी गिना जाता है (पहला तर्क है)।

लिनक्स पर, यह संस्करण पर निर्भर करता है। वहां का व्यवहार हाल ही में बदल गया जहां यह एक निश्चित स्थान नहीं है।

लिनक्स 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सिस्टम कॉल या बाद में है)।

यह भी ध्यान दें (अभी भी लिनक्स 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नंबर के साथ कैसे आए ? यानी आपने यह कैसे गणना की कि 2097152ARG_MAX आकार के तहत अनुक्रम होगा ?
सर्गी कोलोडियाज़नी

14

यह ARG_MAX के मूल्य पर निर्भर करेगा जो सिस्टम के बीच बदल सकता है। अपने सिस्टम रन के लिए मूल्य का पता लगाने के लिए (उदाहरण के रूप में मेरा परिणाम दिखाते हुए):

$ getconf ARG_MAX
2097152

इसका cpआपके शेल से कोई लेना-देना नहीं है , यह कर्नेल द्वारा लगाई गई एक सीमा है, यह निष्पादित नहीं करेगा ( exec()) यदि उनके तर्क लंबे समय से अधिक हैं ARG_MAX। इसलिए, यदि आपने दी गई तर्क सूची की लंबाई cpARG_MAX से अधिक है, तो cpकमांड बिल्कुल नहीं चलेगी।

आपके मुख्य प्रश्न का उत्तर देने के लिए, cpकोई फाइल नहीं करेगा क्योंकि यह इतने सारे तर्कों के साथ निष्पादित नहीं किया जाएगा। मुझे यह भी उल्लेख करना चाहिए कि यह तर्कों की संख्या पर नहीं बल्कि उनकी लंबाई पर निर्भर करता है। आप बहुत ही कम लेकिन बहुत लंबे फ़ाइल नामों के साथ एक ही मुद्दे पर विचार कर सकते हैं।


इन त्रुटियों को प्राप्त करने का तरीका यह है कि आप अपनी कमांड को लूप में चलाएं:

for file in /src/*; do cp "$file" /dst/; done

क्या इसका मतलब यह है कि निम्न स्तर की भाषाओं की तरह CARG_MAX और वास्तव में लंबे फ़ाइल नाम के साथ समस्या हो सकती है?
हेरोल्ड फिशर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.