पिछली कमांड का अंतिम तर्क क्या है?


12

$_ को पिछली कमांड का अंतिम तर्क कहा जाता है।

तो मुझे आश्चर्य है कि क्यों यह नहीं है EDITOR="emacs -nw"लेकिन EDITORनिम्न उदाहरण में?

"emacs -nw"अंतिम तर्क का हिस्सा क्यों नहीं है?

आम तौर पर, एक तर्क और अंतिम तर्क की परिभाषा क्या है?

धन्यवाद।

$ export EDITOR="emacs -nw"
$ echo $_
EDITOR

3
मुझे लगता है कि यह उसी कारण से है कि शेलचेक आपको उसी लाइन पर चर निर्यात नहीं करने के लिए कहता है जिसे आप उन्हें असाइन करते हैं। असाइनमेंट होता है और फिर चर निर्यात किया जाता है। EDITORनिर्यात करने का एक तर्क है
jesse_b

एफडब्ल्यूआईडब्ल्यू, pdkshऔर dashइसमें वह मूल्य शामिल होगा जो सौंपा गया था, लेकिन ksh93जैसा व्यवहार करेगा वैसा bashही व्यवहार करेगा ।
Kusalananda

zsh: export FOO=bar; echo $_प्रिंट export
ilkachachu

@Jesse_b पूरी बात अंतिम तर्क / संचालन (निर्दिष्ट मूल्य सहित) है, लेकिन इस तथ्य के साथ कुछ करना हो सकता है जो exportएक अंतर्निहित उपयोगिता है।
Kusalananda

ksh: typeset -x FOO=barफिर echo $_प्रिंट करता है FOO, लेकिन बैश declare -x FOO=bar; echo $_प्रिंट में FOO=bar
ilkachachu

जवाबों:


13

बैश चर कार्य प्रक्रियाओं, जब वे तर्क के रूप में की अनुमति हो (के साथ alias, declare, export, local, readonly, और typeset), और कुछ भी करने से पहले (या बल्कि, यह उन्हें कुछ और पहले की पहचान करता है - विस्तार मूल्यों चर करने के लिए आवंटित करने के लिए लागू होता है)। जब इसे शब्द विस्तार के लिए मिलता है export EDITOR, तो शेष कमांड होती है , इसलिए _इसे सेट किया जाता है EDITOR

सामान्यतया, तर्क विस्तार के बाद "शब्द" शेष हैं (जिसमें चर असाइनमेंट और पुनर्निर्देशन शामिल नहीं हैं)।

देखें सरल कमांड विस्तार जानकारी के लिए बैश के मैनुअल में।


और मुझे लगता है declareकि मैं जो वर्णन कर रहा हूँ उससे मेल नहीं खाता ...
स्टीफन किट

खैर, यह बहुत संगत नहीं है। declare a=b; echo $_प्रिंट a=b; export c=d; echo $_सिर्फ प्रिंट करता है caliasलगता है सिर्फ नाम छपता है, localदूसरी ओर पूरे तर्क को छापता है। और readonlyसिर्फ नाम भी छापता है, जो मुझे थोड़ा आश्चर्यचकित करता है क्योंकि मैंने सोचा था readonlyऔर localइसके समान होगा declare
इलकाचू

1
@ilkachu हे, मुझे एहसास हुआ कि (ऊपर देखें)। exportऔर readonlyमें एक साथ घोषित किया गया है setattr.def, declare, local, और typesetघोषित किये गए हैं declare.def, aliasअकेले में खड़ा alias.def
स्टीफन किट

धन्यवाद। जब चर असाइनमेंट का उपयोग कुछ आदेशों के तर्क के रूप में किया जाता है, (1) "(या बल्कि, यह उन्हें किसी और चीज से पहले पहचानता है - चर पर दिए गए मानों पर विस्तार लागू होता है)", तो क्या आप का मतलब है कि वेरिएबल असाइनमेंट करने से पहले मूल्यों में विस्तार होता है? (२) "जब शब्द विस्तार के लिए हो जाता है, तो शेष कमांड EDITOR निर्यात होता है", क्या आपका मतलब है कि विस्तार से पहले परिवर्तनशील असाइनमेंट करना है? दोनों उद्धरण एक दूसरे के विपरीत प्रतीत होते हैं।
टिम

धन्यवाद। मैं थोड़ा उलझन में हूँ। जब चर असाइनमेंट का उपयोग तर्कों alias, declare, export, local, readonlyऔर के रूप में किया जाता है typeset। पहले और आगे क्या होता है? "जब इसे शब्द विस्तार के लिए मिलता है, तो शेष कमांड है export EDITOR", क्या आप समझते हैं कि EDITOR="emacs -nw"विस्तार से पहले चर असाइनमेंट होता है? यदि नहीं, तो शेष कमांड में तर्क के रूप में असाइनमेंट क्यों नहीं है? यदि हाँ, तो चर असाइन किए गए मूल्यों पर विस्तार नहीं होता है तो चर असाइनमेंट करने से पहले क्या करना होगा?
टिम

4

टीएल; डीआर: के मामले में export FOO=bar, बैश अपनी अस्थायी पर्यावरण निर्माण को आमंत्रित करता है, FOO=barउस वातावरण में सेट करता है, फिर एक अंतिम कमांड देता है export FOO। उस बिंदु पर, FOOअंतिम तर्क के रूप में लिया जाता है।


आह, बहुत गाली दी $_:

($ _, एक अंडरस्कोर।) शेल स्टार्टअप पर, शेल या शेल स्क्रिप्ट को लागू करने के लिए उपयोग किए जाने वाले पूर्ण पथनाम पर सेट किया जाता है जिसे पर्यावरण या तर्क सूची में पारित किया गया है। इसके बाद, विस्तार के बाद पिछले तर्क के अंतिम तर्क तक फैलता है। साथ ही निष्पादित किए गए प्रत्येक कमांड को लागू करने के लिए उपयोग किए गए पूर्ण पथनाम पर सेट है और उस कमांड को निर्यात किए गए वातावरण में रखा गया है। मेल की जाँच करते समय, यह पैरामीटर मेल फ़ाइल का नाम रखता है।

आइए कुछ बदलाव देखें:

$ man; echo $_
What manual page do you want?
man
$ man foo; echo $_
No manual entry for foo
foo
$ echo; echo $_

echo
$ echo bar foo; echo $_
bar foo
foo
$ foo=x eval 'echo $foo'; echo $_
x
echo $foo
$ bar() { man $1; }; echo $_
foo
$ for (( i=0; $i<0; i=i+1 )); do echo $i; done; echo $_
foo
$ bar; echo $_
What manual page do you want?
man
$ bar foo; echo $_
No manual entry for foo
foo
$ MANPATH=/tmp; echo $_

$ export MANPATH=/tmp; echo $_
MANPATH

इसलिए हम यहां तीन पैटर्न देखते हैं:

  • कमांड सिस्टम, फ़ंक्शंस, और बिल्ट-इन से आम तौर पर अपेक्षित व्यवहार किया जाता है: $_यदि कोई तर्क नहीं है, तो कमांड नाम पर ही सेट किया जाता है।
  • फ़ंक्शन परिभाषाओं के बाद, लूप और अन्य तार्किक निर्माण: $_संशोधित नहीं है।
  • बाकी सब कुछ: $_काफी अपेक्षित नहीं है; अजीब।

मैंने अजीबता में कुछ अंतर्दृष्टि प्रदान करने के लिए कोड लिख दिया है।

$ ./bash --noprofile --norc -c 'man foo'
lastword=[man]
lastarg=[foo]
$ ./bash --noprofile --norc -c 'export FOO=bar'
lastword=[export]
lastarg=[FOO=bar]
bind_variable, name=[FOO], value=[bar]
before bind_lastarg, lastarg=[FOO]
bind_lastarg, arg=[FOO]
bind_variable, name=[_], value=[FOO]
$ ./bash --noprofile --norc -c 'declare FOO=bar'
lastword=[declare]
lastarg=[FOO=bar]
bind_variable, name=[FOO], value=[(null)]
before bind_lastarg, lastarg=[FOO=bar]
bind_lastarg, arg=[FOO=bar]
bind_variable, name=[_], value=[FOO=bar]

आप देख सकते हैं कि पार्सरlastarg= सभी मामलों में अपेक्षित अंतिम तर्क ( ) देखता है , लेकिन उसके बाद जो होता है वह इस बात पर निर्भर करता है कि बैश के बारे में क्या सोचना चाहिए। Execute_cmd.c, execute_simple_command () देखें ।

के मामले में export FOO=bar, बैश असाइनमेंट बनाता है और फिर चर निर्यात करता है। यह दस्तावेज़ीकरण के दावे के अनुरूप है जो अंतिम तर्क की गणना विस्तार के बाद की गई है।


1
शेल को कैसे पता चलता है कि आप मेल चेक कर रहे हैं?
रैकैंडबॉमनमैन

@rackandboneman की पुष्टि के बिना, मैं आंतरिक आधारित किया की जांच पर शकMAILCHECK
जेफ स्कालर

2

शीर्षक प्रश्न का उत्तर देने के लिए, प्रयास करें !$:

$ export EDITOR="emacs -nw"
$ echo !$
EDITOR=emacs -nw

यह इतिहास विस्तार है। बैश मैनपेज से:

इतिहास विस्तार एक पूर्ण पंक्ति पढ़ने के तुरंत बाद किया जाता है, इससे पहले कि खोल इसे शब्दों में तोड़ दे। यह दो भागों में होता है। सबसे पहले यह निर्धारित करना है कि प्रतिस्थापन के दौरान उपयोग करने के लिए इतिहास सूची से कौन सी रेखा है। दूसरा वर्तमान में शामिल करने के लिए उस लाइन के कुछ हिस्सों का चयन करना है। इतिहास से चुनी गई रेखा घटना है, और उस रेखा के अंश जिन पर काम किया जाता है वे शब्द हैं।

...

इवेंट डिज़ाइनर

...

! एक इतिहास प्रतिस्थापन शुरू करें, को छोड़कर जब एक रिक्त, newline, गाड़ी वापसी, = या (जब extglob खोल विकल्प shopt बिल्डिन का उपयोग करने में सक्षम है)।

...

!! पिछली कमांड का संदर्भ लें। यह `-1 'का पर्यायवाची है।

...

वर्ड डिजाइनर्स

...

$ आखिरी शब्द। यह आमतौर पर अंतिम तर्क है, लेकिन अगर लाइन में केवल एक शब्द है, तो शून्य शब्द का विस्तार होगा।

...

यदि किसी शब्द डिज़ाइनर को इवेंट विनिर्देश के बिना आपूर्ति की जाती है, तो पिछले कमांड को इवेंट के रूप में उपयोग किया जाता है।


आप प्रश्न का शीर्षक भी शब्दशः ले रहे हैं। (ठीक है, यह एक खराब शीर्षक है।) हम सभी देख सकते हैं कि कमांड « export EDITOR="emacs -nw"» में दो शब्द हैं: पहला «« है exportऔर दूसरा « EDITOR="emacs -nw"» है। सवाल वास्तव में पूछ रहा है, "बैश मैन पेज और बैश मैनुअल का क्या मतलब है जब वे कहते हैं कि !_'पिछले कमांड के अंतिम तर्क तक फैलता है', इस बैश $_को EDITORइस मामले में « »पर सेट किया गया है ?" इतिहास विस्तार पर बाश मैन पेज सेक्शन को कॉपी और पेस्ट करना विशेष रूप से उपयोगी नहीं है।
जी-मैन का कहना है कि 'मोनिका'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.