बैश उपनामों का विस्तार कैसे करें


11

कैसे एक उपनाम बनाने के लिए जो वास्तव में बैश में उसी नाम के एक और उपनाम का विस्तार करता है?

क्यों:

मैं कुछ इस तरह GREP_OPTIONSसेट करता .bashrcथा:

GREP_OPTIONS="-I --exclude=\*~"

मेरे पास एक स्क्रिप्ट भी थी (आइए हम कहते हैं setup-java.sh) , जिसे मैं कुछ जावा प्रोजेक्ट्स पर काम करने से पहले कहूंगा। इसमें पंक्ति होगी:

GREP_OPTIONS="$GREP_OPTIONS --exclude-dir=classes"

अगर मैं Sass का उपयोग करता हूं, तो मैं कॉल करूंगा setup-sass.shजिसमें लाइन शामिल है:

GREP_OPTIONS="$GREP_OPTIONS --exclude-dir=\*/.sass-cache"

लेकिन GREP_OPTIONSहटा दिया गया था और स्पष्ट रूप से मानक समाधान या तो एक उपनाम या कुछ स्क्रिप्ट बना रहा है ...


बाश कार्यों के बारे में क्या?
जकुज

2
मैं काफी सहमत हूं - एक फ़ंक्शन का उपयोग करना एक उपनाम से बेहतर विकल्प है।
चार्ल्स डफी

जवाबों:


13

बैश एलियासेस के मूल्यों को एक सरणी BASH_ALIASES में संग्रहीत करता है :

$ alias foo=bar
$ echo ${BASH_ALIASES[foo]}
bar

पैरामीटर विस्तार के साथ हम अंतिम सेट उपनाम (यदि मौजूद है) या डिफ़ॉल्ट मान प्राप्त कर सकते हैं:

alias grep="${BASH_ALIASES[grep]:-grep} -I --exclude=\*~"

अब बस करो setup-java.sh:

alias grep="${BASH_ALIASES[grep]:-grep} -I --exclude=\*~  --exclude-dir=classes"

... और अंत में setup-sass.sh:

alias grep="${BASH_ALIASES[grep]:-grep} -I --exclude=\*~ --exclude-dir=\*/.sass-cache"

यदि तीन पंक्तियों को बुलाया जाता है, तो हमें वह मिलता है जो हम चाहते हैं:

$ echo ${BASH_ALIASES[grep]:-grep}
grep -I --exclude=\*~ -I --exclude=\*~ --exclude-dir=classes -I --exclude=\*~ --exclude-dir=\*/.sass-cache

13

aliases श्रृंखला यदि आप उन्हें रिक्त स्थान के साथ समाप्त करते हैं।

alias print='printf %s\\n ' hey='"hello, fine fellow" '
print hey

hello, fine fellow

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

alias grep='printf "%s " -I --exclude=\*~ '    \
      exdir=' --exclude-dir=classes '          \
      exsass='--exclude-dir=\*/.sass-cache '
grep exdir exsass exdir exsass

-I --exclude=*~ --exclude-dir=classes --exclude-dir=*/.sass-cache --exclude-dir=classes --exclude-dir=*/.sass-cache

7
यह सुंदर भयानक है।
user1717828

वाह, यह बहुत बढ़िया है। यह नहीं जानता था (और शायद इसका ज्यादा उपयोग नहीं करेगा, क्योंकि मुझे लगता है कि यह स्पष्टता के नियम के खिलाफ जाता है ) लेकिन यह जानना अच्छा है! प्रश्न, हालांकि: अंतरिक्ष की शुरुआत में exdirक्यों? (यह सिर्फ सौंदर्य कारणों के लिए संरेखण के लिए है?)
वाइल्डकार्ड

2
@Wildcard: fnmatch(){ alias fnmatch='case $1 in '; while "${1:+:}" 2>&-; do eval 'fnmatch pattern list ;; esac'; shift; done; unalias fnmatch; }; alias pattern='${1:+*}) ' list=': do stuff '; fnmatch "$@"। इसके साथ करना aliasesआपको पैटर्न के विस्तार का अधिक सीधे और अधिक सुरक्षित रूप से उपयोग करने की अनुमति देता है। evalकिसी फ़ंक्शन के भीतर से कॉल करने पर आपको दूसरे संदर्भ w / की आवश्यकता होती है , लेकिन यह तब तक असुरक्षित नहीं होता जब तक कि नाम patternऔर listआपके द्वारा नियंत्रित किए जाते हैं। वे ज्यादातर मामलों में तब भी तोड़ सकते हैं, जब तक कि कुछ हमलावर जानबूझकर सही तरीके से समाप्त नहीं होते हैं case
मोकेसर

1
मैं इस पैटर्न का उपयोग अपने में करता हूं .bashrc: alias sudo='sudo 'यह मुझे मेरे सभी अलियास कमांड को कॉल करने की अनुमति देता है sudo। अंतरिक्ष के बिना यह काम नहीं करेगा
arainone

1
@Wildcard - मैं वास्तव में इस तरह के उपयोग की वकालत नहीं कर रहा था, लेकिन यह सच है कि आप कर सकते हैं, और यह भी सच है कि आपको कोशिश करने के लिए कम से कम थोड़ा पागल होना होगा।
सुबह 15:02

2

यहां एक विस्तार योग्य उपनाम से एक फ़ंक्शन एक बेहतर विकल्प है।

grep_options=( )
grep() {
  exec /usr/bin/grep "${grep_options[@]}" ${GREP_OPTIONS} "$@"
}

इस तरह, आपके पास पर्यावरण में विकल्प जोड़ने के लिए दो विकल्प हैं:

  • grep_optionsसरणी में संशोधन करें ; यह रिक्त स्थान, शाब्दिक ग्लोब वर्ण और अन्य कोने मामलों के विकल्पों का सही ढंग से समर्थन करता है:

    grep_options+=( --exclude-dir=classes --exclude-dir='*/.sass-cache' )
  • पारंपरिक GREP_OPTIONSस्केलर वैरिएबल का उपयोग करें , इसके नुकसान के बावजूद ( इनमें से कुछ को समझने के लिए BashFAQ # 50 देखें ):

    GREP_OPTIONS+=' --exclude-dir=classes '

उस ने कहा, यदि आप चाहते हैं कि आपके विकल्प grepशेल के बाहर लगाए गए उदाहरणों से परिलक्षित हों , तो न तो कोई उपनाम और न ही कोई कार्य करेगा। इसके बजाय, आप वास्तविक grepकमांड की तुलना में अपने पैठ में पहले से रखे एक रैपर स्क्रिप्ट चाहते हैं । उदाहरण के लिए:

# in ~/.bash_profile
[[ -e ~/bin ]] && PATH=$HOME/bin:$PATH

... और ~/bin/grep: में

#!/bin/bash

# load overrides to grep_options on GREP_OPTIONS from local dotfiles
source ~/.bash_profile
source ~/.bashrc

# ...and use them:
exec /usr/bin/grep "${grep_options[@]}" ${GREP_OPTIONS} "$@"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.