मेरी बैश स्क्रिप्ट उपनामों को क्यों नहीं पहचानती है?


216

मेरी ~/.bashrcफाइल में दो परिभाषाएँ हैं:

  1. commandA, जो एक लंबे पथ के लिए एक उपनाम है
  2. commandB, जो बैश लिपि का एक उपनाम है

मैं इन दोनों कमांड के साथ एक ही फाइल को प्रोसेस करना चाहता हूं, इसलिए मैंने निम्नलिखित बैश स्क्रिप्ट लिखी है:


#!/bin/bash

for file in "$@"
    do
    commandA $file
    commandB $file
done

मेरे सत्र से बाहर निकलने और वापस लॉग इन करने के बाद भी, बैश मुझे command not foundइस स्क्रिप्ट को चलाने पर दोनों कमांड के लिए त्रुटियों का संकेत देता है ।

मैं क्या गलत कर रहा हूं?


10
BTW, कोई अन्य मान्यता प्राप्त करने के लिए लॉग इन करने और बाहर जाने की आवश्यकता नहीं है। आपको बस करने की जरूरत है source ~/.bashrc
tshepang

मेरे मामले के लिए मैं SSH एजेंट द्वारा दूर से जुड़ा हुआ था, उर्फ ​​को जोड़ने के बाद जैसे ही मैंने SSH एजेंट को बंद किया और फिर से काम करना शुरू कर दिया।
dav

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

जवाबों:


117

सबसे पहले, जैसा कि ddeimeke ने कहा, डिफ़ॉल्ट रूप से उपनाम गैर-इंटरैक्टिव गोले में विस्तारित नहीं होते हैं।

.bashrcजब तक आप BASH_ENVपर्यावरण चर सेट नहीं करते हैं , दूसरा, गैर-इंटरैक्टिव गोले द्वारा नहीं पढ़ा जाता है ।

लेकिन सबसे महत्वपूर्ण बात: ऐसा मत करो! कृप्या? एक दिन आप उस स्क्रिप्ट को कहीं स्थानांतरित कर देंगे जहाँ आवश्यक उपनाम सेट नहीं हैं और यह फिर से टूट जाएगा।

इसके बजाय पर्यावरण चर को अपनी स्क्रिप्ट में शॉर्टकट के रूप में सेट और उपयोग करें:

#!/bin/bash

CMDA=/path/to/gizmo
CMDB=/path/to/huzzah.sh

for file in "$@"
do
    $CMDA "$file"
    $CMDB "$file"
done

5
यह समाधान सामान्य aliasउपयोग के मामलों के लिए काम नहीं करता है । जैसे alias mv="mv -v --backup=numbered"
Evi1M4chine

@ Evi1M4chine: हाँ, यह करता है। कम से कम बाद में मैंने गाइल्स को अनावश्यक रूप से संपादित किया। लेकिन मापदंडों के लिए एक अलग चर का उपयोग करना बेहतर हो सकता है, वैसे भी।

1
आह, चारों ओर उद्धरणों की कमी पर ध्यान दें $CMDA/ $CMDB... अपरकेस वैरिएबल्स के अलावा खुद को बैश में बैश के लिए आरक्षित किया जा रहा है, और यह वास्तव में काम कर रहा है, उद्धरणों की कमी मुझे वास्तव में असहज बनाती है ... वैसे भी धन्यवाद।
Evi1M4chine

@ Evi1M4chine: उह, क्या? 1. मैंने सबसे हाल के संपादन में खुद को उद्धरण हटा दिए। 2. आपको "बैश के लिए आरक्षित" कहां से मिलेगा? यह पहली बार मैंने इसके बारे में सुना होगा। 3. अगर यह आपको असहज करता है, तो पहली बार में आपको बैश का उपयोग करने के बारे में कैसा महसूस होता है? वैसे भी, विकल्पों के लिए एक अलग चर का उपयोग करें जैसा कि मैंने आपको बताया था।

1
@वेल्स: धारणा यह है कि gizmoपथ पर नहीं है या एक ही नाम के साथ एक कमांड है लेकिन एक उच्च प्राथमिकता है। वरना आप पहले स्थान CMDAपर सीधे सादे सेट कर सकते थे gizmo

161

यदि आप बैश मैनपेज को देखते हैं:

जब शेल इंटरएक्टिव नहीं होता है, तब तक एलियासेस का विस्तार नहीं किया जाता है, जब तक कि एक्सप्लोसिअलीस शेल विकल्प शॉप्ट का उपयोग करके सेट नहीं किया जाता है (नीचे शेल बिल्डिन के तहत शॉप का विवरण देखें)।

तो एक डाल दिया

shopt -s expand_aliases

आपकी स्क्रिप्ट में।

अपनी स्क्रिप्ट में इसे सेट करने के बाद अपनी एलियास फ़ाइल का स्रोत सुनिश्चित करें।

shopt -s expand_aliases
source ~/.bash_aliases

7
मैंने इसे अपनी स्क्रिप्ट में रखा, लेकिन यह अभी भी काम नहीं कर रहा है। वही त्रुटि।
ज़ेड

5
shopt -s expand_aliases source ~/.bash_aliasesमेरे लिए पूरी तरह से काम करता है जोड़ना । अक्सर इस तरह के .bashrc में इंटरेक्टिव शेल डिटेक्शन का एक रूप होता है: # If not running interactively, don't do anything [ -z "$PS1" ] && return@Zaid, हो सकता है कि आप उस फाइल में जो आपने खट्टा किया है, उसके लिए जाँच करना चाहते हैं।
फ्रैंक शूबर्ट

1
अति उत्कृष्ट! मेरी लिपियों को बचाया !! :) टर्मिनल में जानकारी और मैनपेज को पढ़ना / खोजना / ब्राउज़ करना इतना कठिन है कि मैंने अभी बहुत समय पहले ही इंटरनेट पर खोज कर ली ...
कुंभ राशि पावर

2
उत्सुकता से, shopt -s expand_aliasesउपनाम की परिभाषा से पहले लेकिन उपनाम के उपयोग से पहले नहीं जाना पड़ता है। @FrankSchubert में जोड़ना: इंटरेक्टिव शेल डिटेक्शन का उपयोग भी किया जा सकता है $-जिसमें शेल के लिए विकल्प होते हैं, खासकर iयदि शेल इंटरैक्टिव है।
वैध

2
यह एक सही उत्तर नहीं है ... अपने स्क्रिप्ट के अंदर अपने उपनामों का उत्तर देना उत्तर नहीं है। आपका ~/.bash_aliasesअन्य सामान पर निर्भर हो सकता है जो पहले एक इंटरेक्टिव शेल पर लोड किया गया था ... मुझे जो निकटतम चीज़ मिली वह आपके हैशबैंग को #!/bin/bash -liअभी भी सही नहीं बदल रही है । आदर्श रूप से आपको कार्यों का उपयोग करना चाहिए न कि उपनामों का।
स्टेफानोस कलांटज़िस

44

उपनाम निर्यात नहीं किए जा सकते, इसलिए वे शेल स्क्रिप्ट में उपलब्ध नहीं हैं, जिसमें वे परिभाषित नहीं हैं। दूसरे शब्दों में, यदि आप उन्हें परिभाषित करने के ~/.bashrcलिए उपलब्ध नहीं हैं your_script.sh(जब तक आप ~/.bashrcस्क्रिप्ट में स्रोत नहीं हैं, जो मैं सुझा नहीं सकता लेकिन यह ठीक से करने के तरीके हैं)।

हालाँकि, फ़ंक्शंस निर्यात किए जा सकते हैं और शेल स्क्रिप्ट के लिए उपलब्ध होंगे जो एक ऐसे वातावरण से चलाए जाते हैं जिसमें वे परिभाषित हैं। इसे अपने bashrc में रखकर किया जा सकता है:

foo ()
{
    गूंज "हैलो वर्ल्ड!"
}
निर्यात -f फू

जैसा कि बैश मैनुअल कहता है, "लगभग हर उद्देश्य के लिए, शेल कार्यों को उपनामों पर पसंद किया जाता है।"


1
हालांकि यह तकनीकी रूप से इस सवाल का जवाब नहीं है, जैसा कि आप कहते हैं कि आप बस की जगह ले सकता alias commandA=...के साथ commandA() { ... }तो export commandAऔर आप उर्फ के समान व्यवहार मिलता है। तो यह
एलियासेस के

यहाँ समस्या तब है जब आपको एक ऐसे उपनाम की आवश्यकता है जिसे आप बहुत सारे उद्धृत विकल्प पास करते हैं। उदाहरण के लिए, उदाहरण के alias b=bashलिए ऐसा करना आसान है b -c "echo test | grep test"जो कार्यों में करना मुश्किल होगा।
Fmstrat

@Fmstrat: b () { bash "$@"; }तबb -c "echo test | grep test"
डेनिस विलियमसन

11
[cmd line] > bash -i [your script's file path]

iइंटरैक्टिव के लिए है और अपने सूत्रों bashआप के लिए प्रोफ़ाइल।


-5

मैंने पाया कि कभी-कभी बैश स्क्रिप्ट निर्यात को भी नहीं पहचानती है। हालांकि, यह करने के लिए बदल रहा है

#!/bin/sh

मेरे लिये कार्य करता है।


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