zsh:再帰はどこから来るのか

zsh:再帰はどこから来るのか

.zshrcは私が次を持っていると仮定します。

alias ls='ls --color=auto'
alias ll='ls -halF'

予想通りに合計whence lsが返されますls --color=autowhence llls -halF

オプション(help whenceヘルプには何もありません)または<rwhence> ll生成できる行はls --color=auto -halFありますか?

答え1

まず、通常の構成で使用するときにエイリアスが実際に繰り返されることを確認しました。

% PS1='%% ' zsh -f
% alias echo='echo foo'
% echo mlatu
foo mlatu
% alias xxxx='echo bar'
% xxxx gerku
foo bar gerku
% 

もちろん。whenceinオプションを調べたところ、zshall(1)再帰を実行するためのオプションが表示されなかったので、何かを書いてみましょう。

function rwhence {
    local def
    local -a alias
    def=$(builtin whence -v $1)
    print $def
    if [[ $def == *'is an alias for'* ]]; then
        # simplification: assume global aliases do not exist
        alias=( ${(z)def##*is an alias for } )
        # loop detection only at the immediate level
        if [[ $alias[1] != $1 ]]; then
            rwhence $alias[1]
        fi
    fi
}

デフォルトでは、出力を解析してwhence -vエイリアス定義を探し、そうであれば最初のコマンドワードを取得するか、既に見ているものでない場合は繰り返します。私はまったく使用していないグローバルエイリアスのサポートがより複雑です。

% rwhence xxxx
xxxx is an alias for echo bar
echo is an alias for echo foo
% rwhence echo
echo is an alias for echo foo
% rwhence cat
cat is /bin/cat
% rwhence mlatu
mlatu not found
% 

答え2

関数定義でエイリアスが拡張されるという事実を利用できます。

expand_alias() {
  functions[_alias_]=$1
  print -r -- ${functions[_alias_]}
}

それから:

$ alias 'a=a;b'
$ alias 'b=b;a x'
$ alias -g 'x=foo'
$ expand_alias a
    a
    b
    a foo

(もちろんそれを実行する拡大するエイリアス拡張を無効にしない限り、エイリアス指定は実行と同じではありませんa

関連情報