シェルエイリアスを「スタック」するにはどうすればよいですか?


12

私の.profile(からのshエミュレーションモードでソースされた.zshrc)私は次のスニペットを持っています:

if [ -f /usr/bin/pacmatic ]; then
    alias pacman=pacmatic
fi

# Colorized Pacman output
alias pacman="pacman --color auto"

ただし、2番目のエイリアスは常に最初のエイリアスをオーバーライドします。

% type pacman
pacman is an alias for pacman --color auto

2番目のエイリアスの割り当てが最初の割り当てを「継承」し、/usr/bin/pacmatic存在する場合はエイリアスになるようにするにはどうすればよいpacmatic --color autoですか?

私はエイリアスの代わりに関数を使用することを嫌いではありませんが、ロジックがpacman呼び出されるたびに実行されなかった場合は、それを好むでしょう(毎回実行されるのではなくpacmatic、シェル起動時に一度チェックしたいpacman)。sh-portableスクリプトも好みますが、これが不可能な場合は、完全なzsh構文を使用できます。

(はい、これ--color autopacmaticエイリアスに追加することで簡単に解決できることを認識しています。しかし、Right Way™でそれを行いたいです。)

グーグルやマンページを調べてみましたが、役に立ちませんでした。


正しい方法は、エイリアスの代わりに関数を使用することだと思いました。(少なくともでbash)エイリアスよりも高速であり、簡単にお互いを呼び出すことができると聞きました。
ヴタズ14

回答:


5

シェルaliasは、とほぼ同様に動作し#defineます。つまり、シェルエイリアスを再定義すると、以前のエイリアスがオーバーライドされます。

Right Way TMがどうなるかはわかりませんが、1つのアプローチは、パラメーターを受け取るシェル関数を使用し、それを使用してエイリアスを作成することです。コードスニペットは次のように書き換えられます。

if [ -f /usr/bin/pacmatic ]; then
    pacman() { pacmatic "$@"; }
fi

# Colorized Pacman output
alias pacman="pacman --color auto"

 


さらに、異なるエイリアスを使用していて、一方を他方の定義に使用しようとしても、エイリアスはデフォルトでは非インタラクティブモードで展開されないため機能しません。次を設定して有効にする必要がありますexpand_aliases

shopt -s expand_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).

これは私が望むものに最も近いように見えますが、機能しません。エミュレーションモードとネイティブモードの両方で、をtype pacman返します。ただし、今行った編集が必要なようです。pacman is an alias for pacman --color autoshzsh
虐待

FWIW、同等のzshはsetopt aliasesです。
虐待

OPはを使用していzshます。とにかく、シェルはインタラクティブに見えます。
ミケル

6

エイリアス置換は、対話型ソースから行を読み取るときにのみ実行されます。したがって、2番目のエイリアスは最初のエイリアスの影響を受けないため、リテラル置換になります。

おそらく似たようなもの:

PACMAN=pacman
if [ -f /usr/bin/pacmatic ]; then
    PACMAN=pacmatic
fi

# Colorized Pacman output
alias pacman="${PACMAN} --color auto"

これにより、「pacman」が適切な値に設定され、PACMAN env変数がエクスポートされないため、スクリプトが終了すると消えます。「二重引用符」を使用すると、エイリアスの宣言で変数置換が行われます。呼び出しごとではありません。

私は同様の方法を使用します:

PACMAN=pacman
which pacmatic &>/dev/null && PACMAN=pacmatic
alias pacman="${PACMAN} --color auto"

基本的に、env var PACMANを設定し、パスでpacmaticをテストし、見つかった場合はPACMANを設定し、エイリアスを定義します。

うーん、もう少し最適化できます...

which pacmatic &>/dev/null && PACMAN=pacmatic
alias pacman="${PACMAN:-pacman} --color auto"

ターダー!PACMANが未設定またはヌルの場合は「pacman」に設定し、そうでない場合はPACMANの値に設定し、「which」行でpacmaticに設定します。


エイリアスが「インタラクティブなソース」に対してのみ機能するのはなぜですか?
ミケル

デフォルトでbashは、非対話型モードではエイリアスを展開しませんが、それは「対話型ソース」とどのように同じですか?
ミケル

2

zshでは、aliases連想配列を使用してエイリアスに簡単に追加できます。

alias pacman="${aliases[pacman]-pacman} --color auto"

他のシェルでは、aliasコマンドの出力を使用して、既存のエイリアスについて調べる必要があります。

current_pacman_alias=$(alias pacman 2>/dev/null)
alias pacman="${current_pacman_alias:-pacman} --color auto"

これを可能性として提供していますが、他の回答ですでに示唆されているように変数を使用します。それはより明確であり、使用中pacmaticまたは使用中のものに基づいていくつかのことを異なるように構成したい場合は、変数の値を区別できpacmanます。

pacman==pacmatic 2>/dev/null || pacman=pacman
alias pacman='$pacman --color auto'


0
pacman() ( def_args="--color auto" bin=
    [ -x ${bin:=/usr/bin/pacmatic} ] || bin=
    [ -x ${bin:=/usr/bin/pacman} ] || bin= 
    ${bin:?WHERE THE HELL IS PACMAN????} \
        $def_args "$@"
)

別名は鳥用です。

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