बैश कमांड लाइन और इनपुट सीमा


90

क्या किसी प्रकार का वर्ण सीमा (या अन्य गोले) में लगाया जा सकता है कि इनपुट कितने समय के लिए हो सकता है? यदि हां, तो उस चरित्र की सीमा क्या है?

यानी क्या बैश में एक कमांड लिखना संभव है जो कमांड लाइन को निष्पादित करने के लिए बहुत लंबा है? यदि आवश्यक सीमा नहीं है, तो क्या कोई सुझाई गई सीमा है?


2
इनपुट सीमा से बहुत अलग है ओएस स्तर के तर्क सीमा (ध्यान दें कि कुछ इस तरह के वातावरण चर के रूप में तर्क, के अलावा अन्य बातों के अलावा, यह भी कहा कि एक ओर लागू)। ऑपरेटिंग सिस्टम में पारित जेनरेट कमांड में शेल कमांड की तुलना में कम या अधिक वर्ण हो सकते हैं जो इसे उत्पन्न करता है।
चार्ल्स डफी

जवाबों:


125

कमांड लाइन की लंबाई की सीमा शेल द्वारा नहीं लगाई जाती है, लेकिन ऑपरेटिंग सिस्टम द्वारा। यह सीमा आमतौर पर सौ किलोबाइट की सीमा में होती है। POSIX इस सीमा को दर्शाता है ARG_MAXऔर POSIX अनुरूप सिस्टम पर आप इसके साथ क्वेरी कर सकते हैं

$ getconf ARG_MAX    # Get argument limit in bytes

जैसे सिग्विन पर यह 32000 है, और विभिन्न बीएसडी और लिनक्स सिस्टम पर मैं इसका उपयोग करता हूं 131072 से 2621440 तक कहीं भी है।

यदि आपको इस सीमा से अधिक फ़ाइलों की एक सूची संसाधित करने की आवश्यकता है, तो आप xargsउपयोगिता को देखना चाहते हैं , जो एक कार्यक्रम को बार-बार कॉल करता है जिसमें उपसर्ग तर्क से अधिक नहीं होते हैं ARG_MAX

अपने विशिष्ट प्रश्न का उत्तर देने के लिए, हां, बहुत लंबे तर्क सूची के साथ कमांड चलाने का प्रयास करना संभव है। शेल "तर्क सूची के साथ बहुत लंबा" संदेश के साथ त्रुटि करेगा।

ध्यान दें कि एक प्रोग्राम का इनपुट (जैसा कि स्टडिन या किसी अन्य फ़ाइल डिस्क्रिप्टर पर पढ़ा जाता है) सीमित नहीं है (केवल उपलब्ध प्रोग्राम संसाधनों द्वारा)। इसलिए यदि आपकी शेल स्क्रिप्ट एक चर में पढ़ती है, तो आप इसके द्वारा प्रतिबंधित नहीं हैं ARG_MAX। प्रतिबंध शेल-बिल्डिंस पर भी लागू नहीं होता है।


ठीक जवाब, फिर भी मैं एक स्पष्टीकरण चाहूंगा। अगर मुझे एक निर्माण मिला cmd <<< "$LONG_VAR"और LONG_VAR मान सीमा से अधिक हो गया, तो क्या यह मेरी कमांड को उड़ा देगा?
क्रिज़िस्तोफ Jabło Aprski

1
@ KrzysztofJabłoński LONG_VARपूरी तरह से , क्योंकि सामग्री की स्टड पर पारित कर रहे हैं - और यह पूरी तरह से खोल में किया जाता है; यह एक तर्क के रूप में विस्तारित नहीं है cmd, इसलिए कांटा () / निष्पादन () के लिए ARG_MAX की सीमा खेल में नहीं आती है। अपने आप को आज़माना आसान है: ARG_MAX से अधिक की सामग्री वाली एक चर बनाएं और अपनी कमांड चलाएं।
जेन्स

2
यहाँ स्पष्टीकरण है, रिकॉर्ड के लिए: 8 मेगाबाइट एम 4 ए फ़ाइल के लिए, मैंने किया blah="$(cat /home/schwager/Music/Recordings/20090420\ 131623.m4a)"; cat <<< $blah >/dev/null:। नोट कोई त्रुटि नहीं है।
माइक एस

3
थोड़ा कैविएट। पर्यावरण चर भी गिनते हैं। sysconf manpage > ARG_MAX का उपयोग करना कठिन है क्योंकि यह निर्दिष्ट नहीं है कि निष्पादन के लिए तर्क स्थान का कितना> (3) उपयोगकर्ता के पर्यावरण चर द्वारा खपत होता है।
गेरिट

3
@ user188737 मुझे लगता है कि यह BUGS में एक बहुत बड़ा चेतावनी है । उदाहरण के लिए xargsmacOS 10.12.6 की सीमा है कि यह एक में कितना डालने की कोशिश करता exec()है ARG_MAX - 4096। तो स्क्रिप्ट का उपयोग xargsकर काम कर सकते हैं, जब तक कि एक दिन जब कोई पर्यावरण में बहुत अधिक सामान डालता है। अब इसमें चल रहा है (इसके साथ काम करें:) xargs -s ???
२०:१५ बजे न्यूरालर

44

ठीक है, डेनिज़ेंस। इसलिए मैंने काफी समय तक कमांड लाइन की लंबाई को सुसमाचार के रूप में स्वीकार किया है। तो, किसी की धारणाओं का क्या करें? स्वाभाविक रूप से- उन्हें जांचें।

मेरे पास अपने निपटान में एक फेडोरा 22 मशीन है (जिसका अर्थ है: bash4 के साथ लिनक्स)। मैंने १। अक्षरों में से प्रत्येक में ५००,००० इनकोड (फाइलें) के साथ एक निर्देशिका बनाई है। कमांड लाइन की लंबाई 9,500,000 अक्षर है। इस प्रकार बनाया गया:

seq 1 500000 | while read digit; do
    touch $(printf "abigfilename%06d\n" $digit);
done

और हम ध्यान दें:

$ getconf ARG_MAX
2097152

ध्यान दें, लेकिन मैं यह कर सकता हूं:

$ echo * > /dev/null

लेकिन यह विफल रहता है:

$ /bin/echo * > /dev/null
bash: /bin/echo: Argument list too long

मैं लूप के लिए चला सकता हूं:

$ for f in *; do :; done

जो एक अन्य शेल बिलिन है।

राज्यों के लिए प्रलेखनARG_MAX का सावधानीपूर्वक पढ़ना , निष्पादन कार्यों के लिए तर्क की अधिकतम लंबाई । इसका मतलब है: कॉल किए बिना exec, कोई ARG_MAXसीमा नहीं है । इसलिए यह समझाता है कि शेल बिल्डरों को प्रतिबंधित क्यों नहीं किया जाता है ARG_MAX

और वास्तव में, मैं lsअपनी निर्देशिका कर सकता हूं यदि मेरी तर्क सूची 109948 फाइलें लंबी है, या लगभग 2,089,000 अक्षर (दे या ले) हैं। एक बार जब मैं एक और 18-अक्षर फ़ाइल नाम फ़ाइल जोड़ देता हूं, तो मुझे एक तर्क सूची बहुत लंबी त्रुटि मिलती है । इसलिए ARG_MAXविज्ञापित के रूप में काम कर रहा है: निष्पादन ARG_MAXसूची में अक्षरों से अधिक के साथ निष्पादन विफल हो रहा है- सहित, यह ध्यान दिया जाना चाहिए, पर्यावरण डेटा।


हम्म। मैंने मौजूदा जवाब का मतलब यह नहीं पढ़ा था कि बिल्‍डिन विचाराधीन बाधा के अधीन थे, लेकिन निश्चित रूप से यह देख सकते हैं कि कोई कैसे कर सकता है।
चार्ल्स डफी

6
हां, मुझे लगता है कि यह याद रखना मुश्किल है- खासकर नए कमांड-लाइन एफिशिएंडो के लिए- कि एक बैश बिलियन बनाम फोर्क / एग्जीक्यूटिंग कमांड की स्थिति गैर-स्पष्ट तरीकों से अलग है। मैं वह स्पष्ट करना चाहता था। एक सवाल जो मुझे हमेशा नौकरी के साक्षात्कार में मिलता है (एक लिनक्स सिसडमिन के रूप में), "तो मुझे एक निर्देशिका में फ़ाइलों का एक गुच्छा मिला है। मैं उन सभी पर कैसे लूप करता हूं ..." प्रश्नकर्ता हमेशा लाइन की ओर गाड़ी चला रहा है। लंबाई सीमा और एक खोज / / या xargs समाधान चाहता है। भविष्य में मैं कहने जा रहा हूं, "आह नरक- बस लूप के लिए उपयोग करें। यह इसे संभाल सकता है!" :-)
माइक एस

@ माइक जब आप लूप के लिए कर सकते हैं, यदि आप एक खोज-एक्सएआरजी कॉम्बो का उपयोग कर सकते हैं तो आप बहुत कम कांटा करेंगे और तेज हो जाएगा। ;-)
लेस्टर चेउंग

4
@LesterCheung बिलकुल for f in *; do echo $f; doneनहीं बनेगा (सभी बिलिंस)। इसलिए मुझे पता नहीं है कि एक खोज-एक्सगार्स कॉम्बो तेज हो जाएगा; इसका परीक्षण नहीं किया गया है। वास्तव में, मुझे नहीं पता कि ओपी की समस्या क्या है। हो find /path/to/directoryसकता है कि यह उसके लिए उपयोगी न हो क्योंकि यह फ़ाइल का पथनाम वापस कर देगा। शायद वह एक for f in *पाश की सादगी पसंद करता है । बावजूद, बातचीत लाइन इनपुट सीमा के बारे में है - दक्षता नहीं। तो आइए विषय पर बने रहें, जो कमांड लाइन की लंबाई से संबंधित है।
माइक एस

FWIW, समस्या, जैसा कि मुझे याद है, मैं सिर्फ C में एक शेल लिखने की कोशिश कर रहा था, और यह निर्धारित करता हूं कि मुझे कब तक इनपुट की अनुमति देनी चाहिए।
डेरेक हाल्डेन

-3

1024 जैसी किसी चीज़ की बफर सीमा होती है। रीड बस मिड पेस्ट या इनपुट लटकाएगा। इस उपयोग -e विकल्प को हल करने के लिए।

http://linuxcommand.org/lc3_man_pages/readh.html

-एक इंटरैक्टिव शेल में लाइन प्राप्त करने के लिए रीडलाइन का उपयोग करें

पढ़ने के लिए अपने पढ़ने को बदलें -ई और कष्टप्रद लाइन इनपुट हैंग चली जाती है।


1
यह इस बारे में नहीं है read: "यानी क्या कमांड में लाइन को निष्पादित करने के लिए बहुत लंबा है जो बैश में कमांड लिखना संभव है?"
चाई टी। रेक्स

@ ChaiT.Rex आप सही तरह के हैं, लेकिन यहाँ बात यह है: Readline, यानी बिना नए तरीके से बैश को चलाने की कोशिश करें bash --noediting, और नए प्रॉम्प्ट पर कमांड चलाने की कोशिश करें echo somereallylongword, जहाँ somereallylongword 4090 वर्णों से अधिक लंबा हो। उबंटू 18.04 पर कोशिश की गई, शब्द छोटा हो गया, तो जाहिर है कि यह कुछ करने के लिए है Readline सक्षम नहीं होने के साथ।
आमिर

@Amir दिलचस्प! तुम सही हो! मैंने उत्तर को संपादित करने का प्रयास किया, लेकिन तब मुझे महसूस हुआ कि -e विकल्प इस संदर्भ में बैश पर लागू नहीं होता है (बैश में, यह शेल को त्रुटि पर तुरंत बाहर निकालता है)। और मुझे यकीन नहीं है कि पॉल ने क्यों पढ़ा। वैसे भी, बैश को --noreadline के साथ शुरू करने पर 4-5000 अक्षरों के बीच बफर सीमा होती है। यह एक साइड इफेक्ट है जिसके बारे में मुझे उम्मीद नहीं थी।
माइक एस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.