使zsh别名使用前缀命令

时间:2017-10-18 22:15:43

标签: zsh variable-expansion

某些命令以某种方式操纵环境,然后调用另一个命令。例如,xargs <command> <args>通过标准输入获取参数,并将它们附加到args列表的末尾,然后使用这些参数运行<command>

另外,我可以在zsh配置中定义别名。例如,

alias ll='ls -al'

表示我可以在命令行键入ll,ZSH会将其扩展为ls -al

但是,我无法组合使用这两者。如果我写echo Documents | xargs ll我得到:

ll: command not found

有没有办法指示ZSH在有问题的命令之后扩展别名?例如。 &#34;如果第一个命令是xargs,则展开之后看到的任何其他内容。&#34;

2 个答案:

答案 0 :(得分:1)

您可以定义全局别名:

alias -g ll='ls -al'

请注意,这会将ll 扩展到,它会被视为一个独特的词,而不仅仅是xargs等命令的命令参数。

答案 1 :(得分:0)

根据zsh manual

  

检查shell输入中的每个符合条件的单词,以查看是否为其定义了别名。如果是这样,如果别名的文本位于命令位置(如果它可能是简单命令的第一个单词),或者别名是全局的,则将其替换为别名的文本。 如果替换文字以空格结尾,则shell输入中的下一个单词始终符合别名扩展的条件。使用别名builtin定义别名;可以使用内置的-g选项定义全局别名

全局别名并不好,因为ll中的全局别名echo ll将会扩展。

你的第一个选择是alias xargs='xargs ',额外的空格将导致xargs后面的单词扩展。

但仍有问题。例如,mv通常与nocorrect mv混淆,因此xargs mv会抱怨nocorrect: No such file or directory

我的解决方案是使用以下代码段使其成为一种功能。

function alias_unwrapper {
    local sudo="$1"
    if [[ ! -x "$sudo" ]]; then
       echo "$sudo not found"; return;
    fi
    local cmd=(${(s: :)aliases[$2]}); # let cmd be array of command and arguments
    (($#cmd)) || cmd=($2)             # if cmd has no aliases, use array of a single element
    while (( $#cmd > 0 )) && [[ $cmd[1] == "nocorrect" || $cmd[1] == "noglob" ]]; do
        shift cmd;         # remove beginning garbage
    done
    local args=(${cmd:1}); # origin params of alias
    args+=(${@:3})         # additional params after alias
    $sudo ${cmd[1]} $args        # unwrap the args array
}


function xargs {
    local XARGS=/usr/bin/xargs
    alias_unwrapper $XARGS $@
}

我自己使用上面的代码展开sudowatchparallel等。

相关问题