Como posso “empilhar” aliases de shell?

10

No meu modo de emulação .profile (originado em sh do meu .zshrc ), tenho o seguinte fragmento:

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 "herde" a primeira atribuição, de modo que, se /usr/bin/pacmatic existir, o alias se torne pacmatic --color auto ?

Eu não sou avesso a usar funções em vez de aliases, mas eu preferiria que a lógica não fosse executada sempre que pacman fosse invocado (eu quero pacmatic verificada uma vez, na inicialização do shell, não toda vez que pacman é executado). Eu também prefiro um script sh -portable, mas se isso não for possível, você pode usar a sintaxe zsh completa.

(Sim, estou ciente de que isso poderia ser facilmente resolvido adicionando --color auto ao pacmatic alias. Mas quero fazer o caminho certo.)

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

    
por strugee 13.04.2014 / 08:24

5 respostas

4

Um shell alias se comporta de maneira muito semelhante a um #define , ou seja, a redefinição de um alias de shell substituirá o anterior.

Não sei qual seria o caminho certo TM , mas uma abordagem seria usar uma função de shell que aceita parâmetros e usa isso 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 se você estivesse usando diferentes aliases 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 ativá-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).
    
por 13.04.2014 / 09:49
6

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

Talvez algo parecido:

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

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

Isso definirá 'pacman' como o valor adequado, a variável PACMAN env não será exportada, então desaparecerá quando o script for concluído e o uso de "aspas duplas" assegurará que a substituição de variável ocorra na declaração de o alias, não para cada invocação.

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 em path, se encontrado, configure PACMAN, então defina o alias.

Humm, 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 não estiver definido ou nulo, caso contrário, configure com o valor de PACMAN, defina como pacmatic pela linha 'which'.

    
por 13.04.2014 / 09:34
2

Em zsh, você pode acrescentar facilmente a um alias usando o aliases matriz associativa:

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

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

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

Embora eu esteja oferecendo isso como uma possibilidade, eu usaria uma variável como já sugerido por outras respostas. É mais claro, e você pode discriminar o valor da variável se quiser configurar algumas coisas de maneira diferente com base em qual pacmatic ou pacman está em uso.

pacman==pacmatic 2>/dev/null || pacman=pacman
alias pacman='$pacman --color auto'
    
por 14.04.2014 / 02:07
1
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 "$@"
)

Os apelidos são para as aves.

    
por 14.04.2014 / 02:19
0

Uma versão curta para o segundo alias seria:

alias pacman=$PACMAN' --color auto'
    
por 13.04.2014 / 13:38

Tags