शेल स्क्रिप्ट में एक उपनाम कैसे चलाएं?


101

मेरे पास एक निष्पादन योग्य फ़ाइल है mpiexec, जिसका पूरा रास्ता है ~/petsc-3.2-p6/petsc-arch/bin/mpiexec। चूंकि मैं इस कमांड को अलग-अलग निर्देशिकाओं में (पूरे रास्ते को फिर से टाइप करने के बिना) निष्पादित करना चाहता हूं, इसलिए मैं अपने होम .bashrcफाइल में एक उपनाम सेट करता हूं :

alias petsc="~/petsc-3.2-p6/petsc-arch/bin/mpiexec"  

जो मुझे mpiexecटाइप करके आसानी से कमांड प्रॉम्प्ट पर इस फाइल को निष्पादित करने की अनुमति देता है :

petsc myexecutable

मैंने एक कमांड के रूप में scriptअपने नए उपनाम का उपयोग करते हुए , शेल स्क्रिप्ट फ़ाइल लिखने की कोशिश की petsc। अपनी शेल स्क्रिप्ट को उपयुक्त अनुमति (उपयोग करने chmod) देने के बाद , मैंने स्क्रिप्ट को चलाने का प्रयास किया। हालाँकि, इसने मुझे निम्न त्रुटि दी:

./script: line 1: petsc: command not found

मुझे पता है कि मैं केवल mpiexecफ़ाइल के लिए पूर्ण पथ लिख सकता था , लेकिन हर बार पूर्ण पथ लिखने के लिए यह बोझिल है कि मैं एक नई स्क्रिप्ट लिखना चाहता हूं। क्या कोई तरीका है जो मैं petscस्क्रिप्ट फ़ाइल के अंदर अपने उपनाम का उपयोग कर सकता हूं ? क्या ऐसा कोई तरीका है जिससे मैं अपना संपादन कर सकूं .bashrcया .bash_profileऐसा कर सकूं?


कैसे के बारे में उपनाम जोड़ने के लिए .bash_aliases? यह भी कि सापेक्ष पथ के बजाय निरपेक्ष पथ को कैसे उतारा जाए जैसेalias petsc='/home/user/petsc-3.2-p6/petsc-arch/bin/mpiexec'
नितिन वेंकटेश

@nitstorm: न तो समाधान काम करने लगता है ... मुझे अब भी पहले की तरह ही त्रुटि मिलती है
पॉल

जवाबों:


74
  1. आपके शेल स्क्रिप्ट में पूर्ण पथ का उपयोग करते हैं, फिर एक उपनाम।

  2. आपकी शेल स्क्रिप्ट में, एक वैरिएबल, अलग सिंटैक्स सेट करें

    petsc='/home/your_user/petsc-3.2-p6/petsc-arch/bin/mpiexec'
    
    $petsc myexecutable
    
  3. अपनी स्क्रिप्ट में फ़ंक्शन का उपयोग करें। शायद बेहतर है अगर petscजटिल है

    function petsc () {
        command 1
        command 2
    }
    
    petsc myexecutable
    
  4. स्रोत अपने उपनाम

    shopt -s expand_aliases
    source /home/your_user/.bashrc
    

आप शायद अपने स्रोत को नहीं चाहते हैं .bashrc, इसलिए, IMO, पहले 3 में से एक बेहतर होगा।


16
जब तक आप shopt -s expand_aliasesएक ही स्क्रिप्ट में उपयोग नहीं करते तब तक पॉइंट 4 काम नहीं करता है ।
enzotib

आपका सुझाव 2) काम करता है, लेकिन मैं पहली पंक्ति पेट्सक = "..." लिखने के बिना कई शेल स्क्रिप्ट में एक ही कमांड का उपयोग करने में सक्षम होना चाहता हूं। क्या इसे करने का कोई तरीका है?
पॉल

1
@enzotib - धन्यवाद, मैंने अपने जवाब में इसे जोड़ा।
पैंथर

1
बिंदु 2 में आप एक उपनाम नहीं बल्कि एक चर सेट करते हैं।
पाबूक

1
ओपी द्वारा नहीं पूछा गया लेकिन प्रश्न शीर्षक के लिए प्रासंगिक: प्वाइंट 2 युक्त कमांड के साथ काम नहीं करेगा |। यहां, उपयोग shopt -s expand_aliasesऔर स्थानीय उपनाम, जैसे alias myalias='echo abc|rev'- उपयोग से पहले लाइन-ब्रेक की आवश्यकता होती है (ALIASES देखें man bash)। बिंदु 4: खट्टी फाइल गैर-संवादात्मक निष्पादन को रोक सकती है, अर्थात स्क्रिप्ट में। जल्दी के लिए देखो exitया return, जैसे [ -z "$PS1" ] && return(जांच करता है कि प्राथमिक शीघ्र गैर-सहभागी खोल संकेत सेट नहीं है) या एक चेक भी हो सकते हैं iमें $-( $-खोल विकल्प होते हैं, iइंटरैक्टिव का मतलब है)। man bashउन चरों के लिए देखें ।
वैध

61

शेल कार्यों के पक्ष में उपनाम हटाए जाते हैं। से bashमैन्युअल पृष्ठ:

For almost every purpose, aliases are superseded by shell functions.

एक फंक्शन बनाने के लिए, और इसे सबशेल्स में एक्सपोर्ट करने के लिए, अपने में निम्नलिखित डालें ~/.bashrc:

petsc() {
    ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
}
export -f petsc

तब आप स्वतंत्र रूप से अपनी स्क्रिप्ट से अपनी कमांड को कॉल कर सकते हैं।


यह लगभग काम करता है ... एकमात्र समस्या यह है कि मुझे निष्पादन योग्य "mpiexec" के लिए अलग-अलग झंडे पारित करने में सक्षम होने की आवश्यकता है ... उदाहरण के लिए, मुझे "पालतू-एनसी 40 myexecutable" जैसे कुछ को निष्पादित करने में सक्षम होने की आवश्यकता है। उर्फ "पेट्स"
पॉल

4
@Paul: मैंने "$@"सिर्फ तर्कों को संभालने के लिए जोड़ा ।
enzotib

12

शेल फ़ंक्शन और उपनाम शेल तक सीमित हैं और निष्पादित शेल स्क्रिप्ट में काम नहीं करते हैं। आपके मामले के लिए विकल्प:

  • (यदि आप mpiexecइसके बजाय उपयोग करने के लिए परेशान नहीं करते हैं petsc) $HOME/petsc-3.2-p6/petsc-arch/binअपने PATHचर में जोड़ें । इसे संपादित ~/.profileऔर जोड़कर किया जा सकता है :

    PATH="$HOME/petsc-3.2-p6/petsc-arch/bin:$PATH"

    इन परिवर्तनों को लागू करने के लिए पुनः लॉगिन करें

  • निर्देशिका बनाएँ ~/binऔर

    • एक आवरण लिपि का नाम रखें petsc:

      #!/bin/sh
      exec ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
      
    • यदि प्रोग्राम इसके लिए अनुमति देता है, तो आप शेलस्क्रिप्ट को छोड़ सकते हैं और कमांड का उपयोग करके सिम्कलिन बना सकते हैं:

      ln -s ~/petsc-3.2-p6/petsc-arch/bin/mpiexec ~/bin/petsc

9

बैश 4 में आप विशेष चर का उपयोग कर सकते हैं $BASH_ALIASES:।

उदाहरण के लिए:

$ alias foo="echo test"
$ echo ${BASH_ALIASES[foo]}
echo test
$ echo `${BASH_ALIASES[foo]}` bar
test bar

वैकल्पिक रूप से चर के रूप में परिभाषित करें फिर कमांड प्रतिस्थापन या का उपयोग करें eval

उदाहरण के लिए, जैसे उपनाम को परिभाषित करने के बजाय:

alias foo="echo test"

इसे इस प्रकार परिभाषित करें:

foo="echo test"

बजाय। फिर इसे या तो निष्पादित करें:

find . -type f -exec sh -c "eval $foo" \;

या:

find . -type f -exec sh -c "echo `$foo`" \;

शेल्फ़ फ़ंक्शंस के पक्ष में अलग-अलग उपनामों को हटा दिया गया है, यह उत्तर केवल एक ही ओएस है जिसे स्वीकार किया जाना चाहिए। यहां तक ​​कि पुराने डेबियन 8 में बैश का संस्करण 4 है, इसलिए ${BASH_ALIASES[alias]}यह एक अच्छा विकल्प है। अन्यथा मुझे अन्य चीजों को लागू करने के लिए अपने .bash_aliases की बहुत सारी लाइनों को संपादित करना पड़ा। धन्यवाद।
erm3nda

8

आप अपने स्क्रिप्ट को -i ध्वज के साथ एक इंटरैक्टिव शेल के रूप में निष्पादित करने के लिए बैश करने के लिए बाध्य कर सकते हैं। यह उपनाम और अन्य कार्यों को परिभाषित करने के लिए आपकी .bashrc फ़ाइल को बताएगा ।

उदाहरण:

~ $ grep ll .bashrc
alias ll='ls -lah'
~ $ cat script.sh 
#!/bin/sh

ll
~ $ bash script.sh 
script.sh: line 3: ll: command not found
~ $ bash -i script.sh
..directory contents..

और जानकारी:

$ man bash

2
.bashrcगैर-संवादात्मक SSH कमांड निष्पादन के दौरान भी पढ़ा जाता है (इसीलिए इसमें अंतःक्रियात्मकता की जाँच होती है)
muru

6
ALIASES
   ...
   Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt (see the description of shopt under SHELL BUILTIN COMMANDS
   below).

तो इस सवाल का असली जवाब, विकल्प के बजाय शेल स्क्रिप्ट में वास्तविक उपनामों का उपयोग करने की तलाश करने वालों के लिए है:

#!/bin/bash

shopt -s expand_aliases

alias foo=bar

foo whatever

जैसा कि मैं यह क्यों करना चाहता हूं: असामान्य परिस्थितियों के कारण, मुझे यह सोचकर कि यह एक शेल स्क्रिप्ट है, एक डॉकरफाइल को ट्रिक करने की आवश्यकता है।


4
  1. इन .bash_aliases:

    petsc {
    ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
    }
    

    या फंक्शन को अंदर रखें .bashrc। आमतौर पर .bashrcकेवल कॉन्फिगर की गई सेटिंग्स bashको स्टोर किया जाता है।

  2. टर्मिनल में: source .bash_aliases

  3. इसे कहते हैं: petsc arg(s)

लाभ: आप की जरूरत नहीं है export -f petscमें .bash_aliases। उपनाम हटाए गए हैं, लेकिन .bash_aliasesकार्यों के लिए उपयोग करना ठीक है।


मुझे यह समाधान पसंद है, मैं इसे बाद में कोशिश करूँगा
ग्रीनोनलाइन

2
  1. अपने शेल स्क्रिप्ट में अपने उपनाम का उपयोग करें।
  2. इसे निष्पादित करने के बजाय अपने स्क्रिप्ट को अपने वर्तमान, इंटरेक्टिव शेल में स्रोत करें।

तो अगर आपके पास script.shअपने आदेशों के साथ एक फ़ाइल है, जिसमें उपनाम का उपयोग करना शामिल है, तो बस टाइप करें:

source script.sh

@DavidFoerster यह विधि ठीक काम करती है। .या sourcebuiiltin के साथ एक स्क्रिप्ट सोर्सिंग वर्तमान शेल को इसमें सभी कमांड निष्पादित करने का कारण बनता है। यदि उर्फ ​​विस्तार उस खोल में होता है जिसमें .या sourceचलाया जाता है, तो यह होता है। हालांकि, यह महसूस करना महत्वपूर्ण है कि यह विधि केवल कभी-कभी उपयोगी होती है, क्योंकि अक्सर किसी को अपने स्वयं के वातावरण के साथ, अपने स्वयं के शेल में स्क्रिप्ट निष्पादित करने की आवश्यकता होती है। सामान्य तरीके से निष्पादित किए जाने के इरादे से लिखी गई शेल स्क्रिप्ट को आमतौर पर इसके बजाय खट्टा नहीं होना चाहिए - वे अक्सर सही काम नहीं करेंगे।
एलियाह कगन

@EliahKagan: धन्यवाद। अब मैं समझता हूं कि उत्तर का क्या मतलब है। मैं एक स्पष्टीकरण जोड़ दूँगा।
डेविड फ़ॉस्टर

1

(संपादित करें: जब से मैं एमपिएक्सेक के गलत कॉल को हटाता हूं, तब तक फ़ंक्शन हटा दिया गया है।)

यदि केवल एक चीज जो आपको चाहिए वह है कम टाइपिंग, तो आप सिर्फ $ PATH में फ़ोल्डर क्यों नहीं डालते हैं? या $ PATH में कुछ फ़ोल्डर से mpiexec के लिए एक सहानुभूति बनाते हैं? या (मेरे पसंदीदा) ने एक स्क्रिप्ट में उपनाम रखा है जिसे आप कॉलिंग स्क्रिप्ट में स्रोत मानते हैं?


1
इसका कारण मैं इसे अपने $ PATH में नहीं डाल सकता, क्योंकि मेरे पास एक और निर्देशिका में 'mpiexec' फ़ाइल है जो मेरे $ PATH में अलग है। अगर मैं इस नए 'mpiexec' के लिए रास्ता जोड़ूँ, तो यह शायद उन दोनों को अंजाम देने की कोशिश करेगा ... है ना?
पॉल

1
समझ में नहीं आता कि क्यों नहीं बस का उपयोग करें "$@"
enzotib

2
पॉल, यह PATH में पहले वाले एक को निष्पादित करने की कोशिश करेगा, दोनों में नहीं।
9

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