Como posso "empilhar" aliases de shell?

12

No meu .profile(originado no shmodo de emulação do meu .zshrc), tenho o seguinte snippet:

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

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

No entanto, o segundo alias sempre substitui o primeiro:

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

Como posso fazer com que a segunda atribuição de alias "herda" a primeira atribuição, para que, se /usr/bin/pacmaticexistir, o alias se torne pacmatic --color auto?

Eu não sou avesso a usar funções em vez de aliases, mas eu preferiria que se a lógica não fosse executada toda vez que pacmanfor invocada (quero pacmaticverificar uma vez, na inicialização do shell, nem sempre pacmané executada). Eu também prefiro um shscript portável, mas se isso não for possível, você pode usar a zshsintaxe completa .

(Sim, estou ciente de que isso poderia ser facilmente resolvido anexando- --color autose ao pacmaticpseudônimo. Mas quero fazê-lo da maneira certa ™.)

Eu tentei pesquisar no Google e procurar nas páginas de manual, mas sem sucesso.

strugee
fonte
Eu pensei que o caminho certo era usar funções em vez de pseudônimos. Ouvi dizer que eles são mais rápidos que aliases (pelo menos em bash) e podem facilmente ligar um para o outro.
Wutaz 13/04

Respostas:

5

Um shell aliasse comporta de maneira semelhante a um #define, ou seja, redefinir um alias de shell substituiria o anterior.

Não sei ao certo qual seria o Right Way TM , mas uma abordagem seria usar uma função shell que aceite parâmetros e usá-la para criar um alias. Seu snippet de código pode ser reescrito como:

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

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

 


Além disso, mesmo que você estivesse usando aliases diferentes e estivesse tentando usar um para definir o outro, ele não funcionaria, pois os aliases não são expandidos no modo não interativo por padrão. Você precisa habilitá-lo, definindo expand_aliases:

shopt -s expand_aliases

Citando o manual:

   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).
devnull
fonte
isso parece ser o mais próximo do que eu quero, mas não funciona. type pacmanretorna pacman is an alias for pacman --color auto, tanto no shmodo de emulação quanto no zshmodo nativo . no entanto, parece que a edição que você acabou de fazer é o que eu preciso.
strugee
Fwiw, o equivalente zsh é setopt aliases.
strugee
OP está usando zsh. E o shell parece ser interativo de qualquer maneira.
Mikel
6

A substituição do alias é executada apenas ao ler linhas de fontes interativas. Portanto, o segundo alias não é afetado pelo primeiro, daí a substituição literal.

Talvez algo semelhante:

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

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

Isso definirá 'pacman' para o valor adequado, a variável env PACMAN não será exportada, portanto desaparecerá quando o script terminar e o uso de "aspas duplas" garantirá que a substituição da variável ocorra na declaração do alias, não para cada chamada.

Eu uso um método semelhante:

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

Basicamente, defina o env var PACMAN, teste para pacmatic no caminho, se encontrado, defina PACMAN e defina o alias.

Hmm, você poderia otimizar um pouco mais ...

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

Taa Daa! Defina como 'pacman' se PACMAN estiver desabilitado ou nulo; caso contrário, defina o valor de PACMAN, defina pacmatic pela linha 'what'.

lornix
fonte
Por que aliases funcionariam apenas para "fontes interativas"?
Mikel
Você está certo que, por padrão, bashnão expande aliases no modo não interativo, mas como isso é o mesmo que "fontes interativas"?
Mikel
2

No zsh, você pode facilmente anexar a um alias usando a aliasesmatriz associativa:

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

Em outros shells, você precisa usar a saída do aliascomando para descobrir os aliases existentes.

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

Enquanto estou oferecendo isso como uma possibilidade, eu continuaria usando uma variável, como já sugerido por outras respostas. É mais claro e você pode discriminar o valor da variável se desejar configurar algumas coisas de maneira diferente com base em qual delas está pacmaticou pacmanestá em uso.

pacman==pacmatic 2>/dev/null || pacman=pacman
alias pacman='$pacman --color auto'
Gilles 'SO- parar de ser mau'
fonte
0

Uma versão curta para o segundo alias seria:

alias pacman=$PACMAN' --color auto'
Michael Durrant
fonte
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 "$@"
)

Aliases são para os pássaros.

mikeserv
fonte