bashエイリアスを拡張する方法


11

Bashで同じ名前の別のエイリアスを実際に拡張するエイリアスを作成する方法は?

なぜ:

私は以前は次のようなことにGREP_OPTIONS着手し.bashrcていました:

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

またsetup-java.sh、いくつかのJavaプロジェクトに取り組む前に呼び出すスクリプト(私たちに言っておきます)も用意しました。次の行が含まれます。

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

Sassも使用する場合setup-sass.shは、次の行を含むを呼び出します。

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

しかし、GREP_OPTIONS廃止予定であり、どうやら標準的な解決策はエイリアスまたはスクリプトを作成することです...


bash関数についてはどうですか?
Jakuje

2
私はかなり同意します-関数を使用することはエイリアスよりもはるかに良いオプションです。
Charles Duffy

回答:


13

Bashは、エイリアスの値を次の配列に 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"

3行が呼び出されると、必要なものが得られます。

$ 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
@ワイルドカード: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関数内から呼び出された場合、2番目のコンテキストが必要にpatternなりlistますが、およびの名前がユーザーによって制御されている限り、本質的に危険ではありません。一部の攻撃者が意図的に正しくを終了させない限り、ほとんどの場合、それらは壊れていませんcase
mikeserv 2016年

1
私はこのパターンをmy .bashrcalias sudo='sudo 'で使用しています。これにより、すべてのエイリアスコマンドをの後に呼び出すことができますsudo。スペースがないと機能しません
arainone

1
@ワイルドカード-私はそのような使用を厳密に主張していませんでしたが、あなたができることは事実です。
mikeserv 2016年

2

ここでは、関数は拡張可能なエイリアスよりも優れたオプションです。

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

そうすることで、環境にオプションを追加するための2つのオプションがあります。

  • grep_options配列を修正します。これは、スペース、リテラルグロブ文字、およびその他のコーナーケースを含むオプションを正しくサポートします。

    grep_options+=( --exclude-dir=classes --exclude-dir='*/.sass-cache' )
  • GREP_OPTIONS落とし穴があっても、従来のスカラー変数を使用します(これらのいくつかを理解するには、BashFAQ#50を参照してください)。

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

とは言ってgrepも、シェルの外で呼び出されたインスタンスにオプションを反映させたい場合は、エイリアスも関数も行いません。代わりに、実際のgrepコマンドよりもPATHの前にラッパースクリプトを配置する必要があります。例えば:

# 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} "$@"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.