Bash takma adları nasıl genişletilir


11

Bash'de aynı ada sahip başka bir takma adı genişleten bir takma ad nasıl oluşturulur?

Neden:

Eskiden böyle bir şeye GREP_OPTIONSayarlamıştım .bashrc:

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

Ayrıca setup-java.shbazı Java projelerinde çalışmadan önce arayabileceğim bir senaryom vardı (diyelim ki ). Şu satırı içerecektir:

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

Ben de Sass kullanırsanız, o zaman setup-sass.shhangi satırı içeren çağırır :

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

Ancak GREP_OPTIONSkullanımdan kaldırıldı ve görünüşe göre standart çözüm bir takma ad veya bir komut dosyası oluşturuyor ...


Bash fonksiyonları ne olacak?
Jakuje

2
Katılıyorum - bir işlevi kullanmak bir takma addan çok daha iyi bir seçenektir.
Charles Duffy

Yanıtlar:


13

Bash, takma adların değerlerini şu şekilde adlandırır BASH_ALIASES :

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

Parametre genişletme ile son ayarlanan takma adı (varsa) veya varsayılan değeri elde edebiliriz:

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

Şimdi sadece şunu yapın setup-java.sh:

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

... ve son olarak setup-sass.sh:

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

Üç hat çağrılırsa, istediğimizi alırız:

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

13

aliases onları boşluklarla bitirirseniz.

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

hello, fine fellow

Yeterince çılgınsanız, tüm komut dosyalarını bu şekilde yazabilirsiniz. Her neyse, bir takma adı genişletmek istiyorsanız, genişletmek istediğiniz takma adın bir alanda sona erdiğinden emin olun ve bir takma adı yapıştırın.

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
Bu korkunç güzel.
user1717828

Vay canına, bu harika. Bunu bilmiyordum (ve muhtemelen çok fazla kullanmayacağım, çünkü netlik kuralına aykırı olduğunu düşünüyorum ) ama bilmek güzel! Ancak soru: Neden başlangıçtaki boşluk exdir? (Bu sadece estetik nedenlerle uyum için mi?)
Wildcard

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 "$@". Bunu yapmak aliases, desenlerin genişlemelerini daha doğrudan ve daha güvenli bir şekilde kullanmanıza izin verir. evalBir işlev içinden çağrıldığında ikinci bir bağlama ihtiyacınız vardır , ancak patternve listisimleri sizin tarafınızdan kontrol edildiği sürece doğal olarak güvenli değildir . Çoğu durumda, bazı saldırganlar bilerek doğru şekilde sona ermedikçe, olmasalar bile kırılabilirler case.
mikeserv

1
Bu kalıbı my .bashrc: alias sudo='sudo 'öğesinde kullanıyorum. Bu , a sudo. Alan olmadan işe yaramaz
arainone

1
@Wildcard - Böyle bir kullanımı tam olarak savunmuyordum, ancak yapabileceğiniz doğrudur ve denemek için en azından biraz deli olmanız gerektiği de doğrudur.
mikeserv

2

Bir işlev, burada genişletilebilir bir takma addan daha iyi bir seçenektir.

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

Bu şekilde, ortama seçenekler eklemek için iki seçeneğiniz olur:

  • Onaylanmasına grep_optionsdizi; bu, boşluklar, gerçek harf karakterleri ve diğer köşe durumları olan seçenekleri doğru bir şekilde destekler:

    grep_options+=( --exclude-dir=classes --exclude-dir='*/.sass-cache' )
  • GREP_OPTIONSTuzaklarına rağmen geleneksel skaler değişkeni kullanın ( bunlardan bazılarını anlamak için BashFAQ # 50'ye bakın ):

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

Bununla birlikte, seçeneklerinizin grepkabuğun dışında çağrılan örneklerle yansıtılmasını istiyorsanız , ne bir takma ad ne de bir işlev gerçekleşmez. Bunun yerine, PATH'nize gerçek grepkomuttan daha önce yerleştirilmiş bir sarmalayıcı komut dosyası isteyeceksiniz . Örneğin:

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

... ve içinde ~/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} "$@"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.