如何“堆叠” shell别名?


12

在我的.profilesh从我的仿真模式中获取.zshrc)中,我有以下代码段:

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

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

但是,第二个别名始终会覆盖第一个别名:

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

我怎样才能使第二个别名分配“继承”第一个分配,从而使/usr/bin/pacmatic别名(如果存在)成为pacmatic --color auto

我不反对使用函数而不是别名,但是如果不是每次pacman都调用逻辑时就不愿意使用它(我想pacmatic在shell启动时检查一次,而不是每次pacman都运行)。我也希望使用sh-portable脚本,但是如果不可能,则可以使用完整zsh语法。

(是的,我知道,这很容易通过附加来解决--color autopacmatic别名。但我想这样做的正确之道™)。

我尝试了Google搜索并浏览了联机帮助页,但无济于事。


我认为正确的方法是使用函数而不是别名。我听说它们比别名更快(至少在中bash),它们可以轻松地相互调用。
Wutaz 2014年

Answers:


5

Shell的alias行为与相似#define,即重新定义Shell别名将覆盖前一个别名。

我不确定什么是Right Way TM,但是一种方法是使用接受参数的shell函数并使用该函数创建别名。您的代码段可以重写为:

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返回return 。但是,看起来您刚刚所做的编辑才是我所需要的。pacman is an alias for pacman --color autoshzsh
凌晨

FWIW,zsh等效于setopt aliases
2014年

OP正在使用zsh。而且外壳似乎是交互式的。
Mikel

6

仅当从交互式来源读取行时才执行别名替换。因此,第二个别名不受第一个别名的影响,因此不受字面替换。

也许类似的东西:

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"

基本上,设置环境变量PACMAN,测试路径中的pacmatic,如果找到,则设置PACMAN,然后定义别名。

嗯,您可以优化更多...

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

塔阿达!如果PACMAN未设置或为null,则设置为“ pacman”,否则,将其设置为PACMAN的值,并在“哪”行中将其设置为pacmatic。


为什么别名仅适用于“交互源”?
Mikel

没错,默认情况下bash不会在非交互模式下扩展别名,但是与“交互源”有什么相同?
Mikel 2014年

2

在zsh中,您可以使用aliases关联数组轻松附加到别名:

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

在其他Shell中,您需要使用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 "$@"
)

别名用于鸟类。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.