zsh:递归从何而来

zsh:递归从何而来

假设我的.zshrcI 有:

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

正如预期的那样,whence ls返回ls --color=auto和。whence 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除非您禁用别名扩展)。

相关内容