2015-12-21 11 views
13

"ag"実行可能ファイルが見つかった場合、エイリアスを定義する最良の方法は何ですか?シェルの "条件付き"エイリアスを定義する最良の方法

if (($+commands[ag])) ; then alias grep='ag'; fi 

または

[[ -s $(which ag) ]] && alias grep='ag' 

または

if $(which ag >& /dev/null); then alias grep='ag'; fi 

か...?

私は、より堅牢で、パフォーマンスが高く、携帯性が高いということを意味します(Bash、Zsh)。

あなたのアドバイスは何ですか?

答えて

9

あなたが提案している(ほとんどの場合、移植性のない)代替品に比べて、単純明白なPOSIXの変種にはどのような欠点があるのか​​わかりません。

type ag >/dev/null 2>&1 && alias grep=ag 
+0

すてきで清潔です。基本的に私の質問に答える。 – user3341592

+0

サイド質問: '' 'type ag>&/ dev/null'''または単純に' '' 'type ag>/dev/null'''を使用する方がよいでしょうか? – user3341592

+1

前者は移植性がありません。 stderrをリダイレクトする場合は、stdoutとstderrの両方に '2/dev/null'または'/dev/null 2>&1'があります。 – tripleee

1

は、私が(その出力形式が指定されていないので、それはPOSIXではないので、私はwhichを使用していないと何も代わりにサイレントであることの発見されなかったとき、それは文句を)すべてのBourne遺産シェルへの移植のために、このpathto機能を使用します。

あなたが pathtoを呼び出す回数が無視できるため、パフォーマンスに関しては

test "`pathto less`" != "" && alias more=less 

とともに、見つけたときに与えられた任意の実行可能ファイルのパス名をエコー表示

pathto() { 
     DIRLIST=`echo $PATH|tr : ' '` 
     for e in "[email protected]"; do 
       for d in $DIRLIST; do 
         test -f "$d/$e" -a -x "$d/$e" && echo "$d/$e" 
       done 
     done 
} 

は、あなたが気にしてはいけません。あなたの最初の2つの例は移植不可能な(())[[ ]]構成を使用しているので、避けてください。

PATHの空の部分は特に扱いません。セキュリティ上の理由から、.のように避けてください。

+2

'$ PATH'のエントリにスペースが含まれていると、これは信頼できません。しかし、配列のない(そして '<(...)'なしの)Bourneシェルでは、いくつかの作業が必要になります(ただし、出力として 'echo'を保つことによって、通常のパイプでこれを使用でき、' printf' '' \ 0'''を出力することができます...と思います)。また、$ DIATHISTの 'for d 'ループでドロップされたときにそれらを完全に無視するので、空の' $ PATH'値を扱う*方法もあります。それは、シェル自体が現在のディレクトリでコマンドを見るという事実を見逃すことになるということを意味しています。 –

+1

これは、 'test'に非推奨の' -a'引数も使用します。コマンド名自体にスペースが含まれている場合( '$ PATH'-with-spacesの問題を無視して)、複数のコマンドで使用することはできません。 (そして、はい、私は真剣にこの問題が起きるとは思っていませんが、とにかく言及する価値があると考えました) –

+0

@EtanReisnerあなたのpedantryは感謝しています! :-) メリークリスマス。 – Jens

関連する問題