Comment «empiler» des alias de shell?

12

Dans mon .profile(provenant en shmode d'émulation de mon .zshrc), j'ai l'extrait de code suivant:

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

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

Cependant, le deuxième alias remplace toujours le premier:

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

Comment puis-je faire en sorte que la deuxième affectation d'alias "hérite" de la première affectation, de sorte que s'il /usr/bin/pacmaticexiste, l'alias devienne pacmatic --color auto?

Je ne suis pas opposé à l'utilisation de fonctions au lieu d'alias, mais je préférerais que la logique ne soit pas exécutée à chaque pacmaninvocation (je veux pacmaticvérifier une fois, au démarrage du shell, pas à chaque pacmanexécution). Je préférerais également un shscript -portable, mais si ce n'est pas possible, vous pouvez utiliser la zshsyntaxe complète .

(Oui, je suis conscient que cela pourrait facilement être résolu en ajoutant --color autoà l' pacmaticalias. Mais je veux le faire de la bonne façon ™.)

J'ai essayé Google et en parcourant les pages de manuel, mais en vain.

strugee
la source
Je pensais que la bonne façon était d'utiliser des fonctions plutôt que des alias. J'ai entendu dire qu'ils sont plus rapides que les alias (au moins dans bash) et qu'ils peuvent facilement s'appeler.
Wutaz

Réponses:

5

Un shell aliasse comporte de manière assez similaire à a #define, c'est-à-dire que la redéfinition d'un alias de shell remplacerait le précédent.

Je ne suis pas sûr de ce que serait le Right Way TM , mais une approche consisterait à utiliser une fonction shell qui accepte des paramètres et à l'utiliser pour créer un alias. Votre extrait de code peut être réécrit comme suit:

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

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

 


De plus, même si vous utilisiez différents alias et tentiez d'en utiliser un pour définir l'autre, cela ne fonctionnerait pas car les alias ne sont pas développés en mode non interactif par défaut. Vous devez l'activer en définissant expand_aliases:

shopt -s expand_aliases

Citant du manuel:

   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
la source
cela semble être le plus proche de ce que je veux, mais cela ne fonctionne pas. type pacmanrenvoie pacman is an alias for pacman --color auto, à la fois en shmode émulation et en zshmode natif . cependant, on dirait que la modification que vous venez de faire est ce dont j'ai besoin.
strugee
FWIW, l'équivalent zsh est setopt aliases.
strugee
OP utilise zsh. Et le shell semble être interactif de toute façon.
Mikel
6

La substitution d'alias n'est effectuée que lors de la lecture de lignes à partir de sources interactives. Le deuxième alias n'est donc pas affecté par le premier, d'où le remplacement littéral.

Peut-être quelque chose de similaire:

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

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

Cela définira «pacman» à la valeur appropriée, la variable env PACMAN n'est pas exportée, donc elle disparaîtra à la fin du script, et l'utilisation de «guillemets doubles» garantira que la substitution de variable se produira lors de la déclaration de l'alias, pas pour chaque invocation.

J'utilise une méthode similaire:

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

Fondamentalement, définissez l'env var PACMAN, testez pacmatic in path, s'il est trouvé, définissez PACMAN, puis définissez l'alias.

Hmm, vous pourriez optimiser un peu plus ...

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

Taa Daa! Définissez sur «pacman» si PACMAN est non défini ou nul, sinon, définissez sur la valeur de PACMAN, défini sur pacmatic par la ligne «which».

lornix
la source
Pourquoi les alias ne fonctionneraient-ils que pour les "sources interactives"?
Mikel
Vous avez raison, par défaut, bashne développe pas les alias en mode non interactif, mais en quoi est-ce la même chose que les "sources interactives"?
Mikel
2

Dans zsh, vous pouvez facilement ajouter à un alias en utilisant le aliasestableau associatif:

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

Dans d'autres shells, vous devez utiliser la sortie de la aliascommande pour connaître les alias existants.

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

Bien que j'offre cela comme une possibilité, j'irais avec l'utilisation d'une variable comme déjà suggéré par d'autres réponses. C'est plus clair et vous pouvez discriminer la valeur de la variable si vous souhaitez configurer certaines choses différemment en fonction de celle pacmaticou de celle qui pacmanest utilisée.

pacman==pacmatic 2>/dev/null || pacman=pacman
alias pacman='$pacman --color auto'
Gilles 'SO- arrête d'être méchant'
la source
0

Une version courte pour le 2ème alias serait:

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

Les alias sont pour les oiseaux.

mikeserv
la source