इन बैश कमांड के निष्पादन में अनुक्रम क्यों मायने रखता है?


10

कुछ असंगतता प्रतीत होती है कि मैं बैश शेल के संबंध में समझ नहीं पा रहा हूं।

यदि मैं निष्पादित करता हूं:

ls;date;time

तीन प्रश्नों के परिणाम अनुक्रम में दिखाए गए हैं।

हालाँकि, दिनांक और समय की स्थिति को बदलने पर, एक त्रुटि संदेश पॉप अप होता है।

इसलिए अगर मैं निष्पादित करता हूं:

ls;time;date

त्रुटि संदेश कहता है bash: syntax error near unexpected token 'date':।

क्या कोई इसे समझा सकता है?


आपकी समस्या time;dateबनाम पर है date;time। ऐसा लगता है कि आउटपुट के साथ पाइपलाइन में bashऔर अंतिम चार के साथ एक समस्या है time। अलग-अलग टर्मिनल एमुलेटर में परीक्षण किए गए परिणाम हैं: - [बैश] $ तारीख; समय # [ठीक] $ समय; तारीख # [ नोटोक ] बैश: अप्रत्याशित टोकन के पास सिंटैक्स त्रुटि `तिथि '$ समय # केवल त्रुटि दिखाई नहीं देती है कि यह है किसी भी तारीख का परिणाम। - [Csh] $ date; समय # [OK] $ समय; तारीख # [OK] - [Tcsh] $ तारीख; समय # [OK] $ समय; तारीख # [OK] - [Ksh] $ date; समय # [ ठीक है] $ समय; तिथि # [ठीक]
मोस्टफा शाहवेरी

मैंने त्रुटि संदेश के लिए स्पष्टीकरण के साथ अपना उत्तर अपडेट किया है। कृपया जांचें कि यह वह उत्तर है जिसकी आपको तलाश थी।
21

जवाबों:


10

timeअपने पाइप लाइन में आदेश नहीं है /usr/bin/timeद्विआधारी, लेकिन पार्टी timeमें निर्मित। तुलना man timeके साथ help time। आप जो त्रुटि देखते हैं, वह timeतर्क को पार्स करने में विफल है । यह या तो मौजूद होना चाहिए या एक नई रूपरेखा होनी चाहिए। यह आपके पहले उदाहरण में एक नई रूपरेखा है लेकिन दूसरे में अनुपस्थित है।

दूसरी तरफ, अगर आप दौड़ने के लिए थे

ls;date;'time'

या

ls;'time';date

जहाँ आसपास के उद्धरण 'time'आरक्षित शब्द के रूप में इसकी स्थिति को निरस्त करते हैं, तो bash को लाइन पार्स करने में कोई समस्या नहीं है। यह अब एक सूची में तीन कमांडों को पार्स करता है, जिसे वह अनुक्रम में निष्पादित करेगा, और /usr/bin/timeकिसी भी मामले में उपयोग त्रुटि की रिपोर्ट करेगा।

परिशिष्ट

यह देखा गया कि हालांकि time ; dateएक त्रुटि पैदा होती है, time ; ; dateनहीं करता है। संभावित व्याख्या यह है कि time ;इसकी व्याख्या बैश के समकक्ष की गई है time <newline>। अभिव्यक्ति time ; ; dateतो की सूची के रूप में पार्स किया गया है time ;और date

यह उस अवलोकन के अनुरूप है जो कानूनी है time ;और time ; ;साथ ही दूसरा है, जिसे एकल सूची के रूप में सूचीबद्ध time ;किया गया है, जिसमें सूचियों के बाद वैकल्पिक अर्धविराम की अनुमति है।

तो यह बताने का एक और तरीका है कि time ; dateत्रुटि क्यों उत्पन्न होती है, जो अर्धविराम को अलग करके खपत करता है । यह केवल वह कर सकता है क्योंकि एक बैश आरक्षित शब्द है।bash: syntax error near unexpected token 'date'timedatetime


एक अच्छी व्याख्या के लिए धन्यवाद! लेकिन फिर से यह व्यवहार मेरे लिए एक बग जैसा दिखता है: timeएक पूर्ण आदेश की अनुमति देने के लिए माना जाता है, और अर्धविराम को सूचियों को सीमांकित करना है, इसलिए IMO timeकमांड को इसके बाद अर्धविराम का "उपभोग" नहीं करना चाहिए। अन्य अंतर्निहित आदेश (जो तर्क ले सकते हैं) इस तरह के व्यवहार को प्रदर्शित नहीं करते हैं।
व्यवस्थित करें

@ अरेंज कॉम्प्लिमेंटेशन यह है कि समय एक शून्य कमांड की अनुमति नहीं देता है (जो सब कुछ अव्यवस्थित कर देता है), यह केवल कमांड के स्थान पर एक नई पंक्ति की अनुमति देता है । तो time;dateवास्तव में किसी भी व्याख्या में वाक्यात्मक रूप से गलत है। हालांकि time ; और time ; ;उसके बाद भी अवैध होगा। यह बहस किया जा सकता है कि क्या timeके व्यवहार एक बग या केवल undocumented (यह है है आंतरिक रूप से संगत), लेकिन एक बग रिपोर्ट निश्चित रूप से जगह में होगा। क्या आप इसे दर्ज करने के लिए तैयार हैं?
zwets

खैर, मैंने स्रोत (bash4.2: parse.y: lines 1205-1221) को देखा और वहां यह कहता है कि time by itself can time a null commandऔर फिर यह ऐसा करता है $$ = make_simple_command (x, (COMMAND *)NULL);। बग दर्ज करने के लिए मुझे यकीन नहीं है कि 8)
व्यवस्था करें

ध्यान दिया जाना चाहिए कि यह मुद्दा बैश-विशिष्ट है। कर time ; dateमें काम करता है ksh93और mkshकोई त्रुटि के साथ, यहां तक कि हालांकि ksh वहाँ timeकीवर्ड।
सर्गी कोलोडियाज़नी

2

बैश timeकमांड-लाइन्स को पार्स करते समय एक विशेष मामले के रूप में बिल्ट-इन का इलाज करता है ।

जैसा कि बैश मैनपेज में पढ़ा जा सकता है, टाइप की गई लाइन पहले एक सूची में विभाजित है:

pipeline ; pipeline

जहां एक पाइपलाइन है:

[time [-p]] [ ! ] command [ [|⎪|&] command2 ... ]

या हमारे मामले में, बस:

time command

यानी अगर समय मौजूद है, तो कमांड भी मौजूद होना चाहिए

[एक विशेष मामला है जो timeएक नई पंक्ति का पालन करने की अनुमति देता है, लेकिन यह यहां लागू नहीं होता है]

तो, हमारे मामले में, हमारे पास:

time;date

दो पाइपलाइनों में विभाजित किया जा रहा है:

1. time
2. date

और पाइपलाइन 1 अच्छी तरह से नहीं बनी है, क्योंकि हमारे पास timeबिना कमांड के है। इसलिए त्रुटि।

ध्यान दें कि कमांड-लाइन timeयहां काम नहीं करती है:

$ /usr/bin/time;date
Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose]

बैश इसे 2 पाइपलाइनों में अपेक्षित रूप से पार करता है:

1. /usr/bin/time
2. date

और /usr/bin/timeफिर बिना किसी तर्क के साथ चलने से इंकार कर दिया। ध्यान दें कि यह /usr/bin/timeबैश से त्रुटि नहीं है।

बैक-टिक का काम करने का कारण यह है कि बैक-टिक स्टॉप timeपाइपलाइन के भीतर एक विशेष तत्व के रूप में व्याख्या किया जा रहा है।

यानी पीछे-टिक के साथ:

`time`;date

इसे दो पाइपलाइनों के रूप में रखा गया है:

1. `time`
2. date

याद रखें कि एक पाइपलाइन, हमारे मामले में है:

[time] command

और शुरू में समस्या यह थी कि हमारे पास timeकोई आदेश नहीं था, जिसकी अनुमति नहीं है। लेकिन अब हमारे पास केवल कमांड है:

`time`

पूर्ववर्ती के बिना time, चूंकि बैक-टिक्स का अर्थ है कि timeकमांड के रूप में व्याख्या की जाती है, पूर्ववर्ती शब्द के रूप में नहीं।

तो बैश तो timeबिना किसी आर्ग के साथ अपने बिलिन को चलाता है , जिसे स्वीकार किया जाता है। यह कोई आउटपुट नहीं पैदा करता है, और हम कोई त्रुटि नहीं देखते हैं।

ध्यान दें कि:

`time`

वास्तव में बिल्ट-इन का परिणाम चलता timeहै, यानी जो कुछ भी timeनिर्मित होता है वह स्टडआउट पर चलता है । लेकिन जब timeसे अपने दम पर कुछ भी लिखने के लिए नहीं है, यह काम करने के लिए प्रकट होता है।

अंत में, यह नोट किया गया है कि यह काम करता है:

time ; ; date

जो मैं समझा नहीं सकता, दुख की बात है :)


मुझे लगता है कि आपका स्पष्टीकरण बेहतर है, लेकिन यह अभी भी मुझे अजीब लगता है। ;dateदेता है bash: syntax error near unexpected token ;, लेकिन time ;dateदेता है bash: syntax error near unexpected token date, तो ऐसा लगता है कि बैश समय ", तारीख" के रूप में कमांड का इलाज नहीं करता है। दिलचस्प है, time ; ; dateकाम करता है।
व्यवस्थित करें

हाँ, धन्यवाद @ व्यवस्था, यह काफी अजीब है। मैं उत्तर को थोड़ा अपडेट करूंगा।
cdmackay

ठीक है, @ व्यवस्थित करें, फिर से लिखा है। अभी भी अपने अंतिम हालांकि व्याख्या नहीं कर सकते ... आह।
cdmackay

@cdmackay आप बैकटिक्स और उद्धरण मिला रहे हैं। इसे उद्धृत करके 'time'एक आरक्षित शब्द के रूप में इसका अर्थ खो देता है। इसे बैकटैक करने से यह सब- सब्स्क्राइब में निष्पादित हो जाता है जिसका आउटपुट कमांड में स्पिल हो जाता है। इसका चर्चा से कोई लेना-देना नहीं है। तथ्य की बात के रूप में, आपका उदाहरण `time\';dateआपके दावे के विपरीत साबित होता है: यह आपके तर्क से एक त्रुटि देना चाहिए क्योंकि /usr/bin/timeएक तर्क की आवश्यकता होती है। इसका कारण यह नहीं है कि जिस सब-सब्मिट में वह इसे निष्पादित करता है वह timeएक बार फिर आरक्षित शब्द है ।
zwets

@ व्यवस्था दोनों वाक्यविन्यास त्रुटियां हैं और दोनों एक ही स्थान के पास होने की सूचना है, इसलिए मुझे वहां असंगतता नहीं दिखती । एक बार जब यह सिंटैक्स त्रुटि भूमि में प्रवेश करता है, तो आप एक पार्सर से इसका रास्ता जानने की उम्मीद नहीं कर सकते। यदि आपको एक पार्सर की आवश्यकता होगी, तो उसे न केवल कानूनी सिंटैक्स पता होना चाहिए, बल्कि हर संभव अवैध निर्माण का सिंटैक्स भी होना चाहिए , जो परिभाषा द्वारा असंभव है।
zwets
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.