उपनाम और कार्य


17

बैश मैनुअल से

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

एक फ़ंक्शन परिभाषा को पढ़ने पर दो वाक्य "उपनामों का विस्तार किया जाता है, जब फ़ंक्शन निष्पादित नहीं किया जाता है" और "फ़ंक्शन में परिभाषित उपनाम तब तक उपलब्ध नहीं होते हैं जब तक कि फ़ंक्शन निष्पादित नहीं किया जाता है" एक दूसरे के विपरीत प्रतीत होते हैं।

क्या आप बता सकते हैं कि उनका क्या मतलब है?


अच्छा प्रश्न! मैंने आज कुछ नया किया है। मैंने 2 चीजें सीखीं, वास्तव में: 1) यह जानकारी उर्फ ​​विस्तार के बारे में है जिस समय फ़ंक्शन पढ़ा जाता है, और 2) कि मुझे वास्तव में बैश मैनुअल को ध्यान से पढ़ना चाहिए (जो मुझे लगा कि मैंने पहले ही किया था, लेकिन स्पष्ट रूप से ^ ^ नहीं। )
ओलिवियर दुलैक

4
मुख्य सवाल यह है कि क्या किसी को भी गैर-सक्रिय मोड में उपनामों का उपयोग करना चाहिए? यही कारण है कि कार्य हैं, और उपनाम केवल स्क्रिप्टिंग को और अधिक त्रुटि-प्रवण बनाते हैं। मुझे वास्तव में ऊपर दी गई जानकारी की आवश्यकता नहीं है, क्योंकि मुझे केवल .bashrcबहुत ऊपर फाइलों में उपनामों का सामना करना पड़ा है ।
ओरियन डेस

जवाबों:


29
  1. उपनाम तब विस्तारित होते हैं जब फ़ंक्शन परिभाषा को पढ़ा जाता है, तब नहीं जब फ़ंक्शन निष्पादित होता है ...

    $ प्रतिध्वनि "आलसी कुत्ते पर त्वरित भूरे लोमड़ी कूदता है।" > मायफाइल
     
    $ उर्फ ​​मायलियास = बिल्ली
     
    $ myfunc () {
    > मायलियास myfile
    >}
     
    $ myfunc
    तेज, भूरी लोमडी आलसी कुत्ते के उपर कूद गई।
     
    $ उर्फ ​​मायलियास = "एलएस-एल"
     
    $ मलयस मायफाइल
    -rw-r - r-- 1 myusername mygroup 45 Dec 13 07:07 myfile
     
    $ myfunc
    तेज, भूरी लोमडी आलसी कुत्ते के उपर कूद गई।

    भले ही myfuncकॉल करने के लिए परिभाषित किया गया था myalias, और मैंने फिर से परिभाषित किया है myalias, फिर myfuncभी मूल परिभाषा को निष्पादित करता है myalias। क्योंकि फ़ंक्शन परिभाषित होने पर उपनाम का विस्तार किया गया था। वास्तव में, शेल अब उस myfuncकॉल को याद नहीं करता है myalias; यह केवल यह जानता है कि myfuncकॉल cat:

    $ प्रकार myfunc
    myfunc एक फ़ंक्शन है
    myfunc ()
    {
    बिल्ली मायफाइल
    }
  2. ... किसी फ़ंक्शन में परिभाषित उपनाम तब तक उपलब्ध नहीं होते हैं जब तक कि फ़ंक्शन निष्पादित नहीं किया जाता है।

    $ प्रतिध्वनि "आलसी कुत्ते पर त्वरित भूरे लोमड़ी कूदता है।" > मायफाइल
     
    $ myfunc () {
    > उर्फ ​​मायलियास = बिल्ली
    >}
     
    $ मलयस मायफाइल
    -बाश: म्यलियास: कमान नहीं मिली
     
    $ myfunc
     
    $ मलयस मायफाइल
    तेज, भूरी लोमडी आलसी कुत्ते के उपर कूद गई।

    myaliasजब तक उर्फ उपलब्ध नहीं है myfuncसमारोह निष्पादित किया गया है। (मेरा मानना ​​है कि यदि उर्फ ​​को परिभाषित करने वाले कार्य को परिभाषित करने के लिए उर्फ ​​को परिभाषित करने के लिए पर्याप्त था, तो इसे परिभाषित करना अजीब होगा।)


4
+1, अच्छा जवाब। इसके लिए एक महत्वपूर्ण "कोरोलरी" यह है कि यदि कोई स्क्रिप्ट में फ़ंक्शंस और उपनामों को परिभाषित करना चाहता है, तो फ़ंक्शंस परिभाषाओं से पहले एलियास परिभाषा को बेहतर तरीके से रखे! (स्पष्ट, अब, जवाब दिया, लेकिन मुझे यह नहीं पता था)।
ओलिवियर दुलैक

धन्यवाद। मुझे लगता है कि एक अंतर्निहित मुद्दा एक फ़ंक्शन की परिभाषा को चलाने और फ़ंक्शन को कॉल करने के बीच का अंतर है। विशेष रूप से, किसी फ़ंक्शन की परिभाषा को चलाने के दौरान और फ़ंक्शन को कॉल करने के दौरान क्रमशः कौन से शेल ऑपरेशन किए जाते हैं? क्या कोई शेल ऑपरेशन है जो किसी फ़ंक्शन की परिभाषा को चलाने और फ़ंक्शन को कॉल करने, या फ़ंक्शन की परिभाषा को चलाने या फ़ंक्शन को कॉल करने के दौरान शेल ऑपरेशन के गैर-अतिव्यापी सेट को निष्पादित करने के दौरान किया जाता है?
टिम

खैर, यह कार बनाने और कार चलाने के बीच के अंतर की तरह है। या फिर सैंडविच खरीदकर सैंडविच खा रहे हैं। मैंने आपके अन्य प्रश्न का अधिक विस्तृत उत्तर प्रदान किया है ।
जी-मैन ने

धन्यवाद। बैश मैनुअल और आपके उत्तर से उद्धरण पुन: प्राप्त करने के बाद, मैं किसी फ़ंक्शन को निष्पादित करने के अर्थ के बारे में उलझन में हूं। क्या इसका मतलब किसी फ़ंक्शन की परिभाषा को निष्पादित करना है, या फ़ंक्शन को कॉल करना है? देखें unix.stackexchange.com/q/384209/674
टिम

1

मुझे उस उत्तर की आवश्यकता है जो पहले वाक्य द्वारा बताया गया है जब मैं अपने में स्निपेट के नीचे कोशिश करता हूं.bashrc

alias ls='\ls -F --color=auto --show-control-chars'
alias ll='ls -ahl'
function lf_macro() {
    local CMD=${1:-ls} DIR=${2:-.};
    $CMD $(find $DIR -maxdepth 1 -type f);
}
function lf() { lf_macro ll "$1"; }
function lsf() { lf_macro ls "$1"; }     # list all file, no directories

के बाद unalias -a; source ~/.bashrc, मैं निष्पादित करने की कोशिश करता हूं lfऔर lsf,

$ lf
-bash: ll: command not found

$ lsf
./file1 ./file2 ./script.sh ...     # no color, no control-chars

$ ls $(find -maxdepth 1 -type f)
./file1 ./file2 ./script.sh* ...

यह स्पष्ट रूप से लगता है कि उपनामों को कार्य परिभाषा में विस्तारित किया गया है, कार्य निष्पादन नहीं, क्योंकि :

  • जब मैं निष्पादित करता हूं lf, त्रुटि -bash: ll: command not found, और
  • जब मैं निष्पादित करता हूं lsf, /usr/bin/lsउपयोग किया जाता है, न कि उपनाम रूप, न ही कोई रंग हाइलाइट, और निष्पादन योग्य फ़ाइल के बाद कोई नियंत्रण वर्ण नहीं।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.