¿Cómo puedo "apilar" alias de shell?


12

En mi .profile(originado en shmodo de emulación de mi .zshrc) tengo el siguiente fragmento:

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

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

Sin embargo, el segundo alias siempre anula al primero:

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

¿Cómo puedo hacer que la segunda asignación de alias "herede" la primera asignación, de modo que si /usr/bin/pacmaticexiste, el alias se convierta pacmatic --color auto?

No soy reacio a usar funciones en lugar de alias, pero preferiría que no se realizara la lógica cada vez que pacmanse invoca (quiero pacmaticcomprobar por una vez, en el inicio del shell, no cada vez que pacmanse ejecuta). También preferiría un shscript portátil, pero si esto no es posible, puede usar la zshsintaxis completa .

(Sí, soy consciente de que esto podría resolverse fácilmente agregando --color autoel pacmaticalias. Pero quiero hacerlo de la manera correcta).

He intentado buscar en Google y revisar las páginas de manual, pero fue en vano.


Pensé que la forma correcta era usar funciones en lugar de alias. He oído que son más rápidos que los alias (al menos en bash), y pueden llamarse fácilmente entre sí.
Wutaz

Respuestas:


5

Un shell se aliascomporta de manera bastante similar a un #define, es decir, redefinir un alias de shell anularía el anterior.

No estoy seguro de cuál sería el Right Way TM , pero un enfoque sería utilizar una función de shell que acepte parámetros y usarla para crear un alias. Su fragmento de código podría reescribirse como:

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

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

 


Además, incluso si usara diferentes alias y tratara de usar uno para definir el otro, no funcionaría ya que los alias no se expanden en modo no interactivo de manera predeterminada. Debe habilitarlo configurando expand_aliases:

shopt -s expand_aliases

Citando del 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).

Esto parece ser lo más cercano a lo que quiero, pero no funciona. type pacmanvuelve pacman is an alias for pacman --color auto, tanto en shmodo de emulación como en zshmodo nativo . Sin embargo, parece que la edición que acabas de hacer es lo que necesito.
strugee

FWIW, el equivalente de zsh es setopt aliases.
strugee

OP está usando zsh. Y el shell parece ser interactivo de todos modos.
Mikel

6

La sustitución de alias solo se realiza al leer líneas de fuentes interactivas. Entonces, el segundo alias no se ve afectado por el primero, de ahí el reemplazo literal.

Quizás algo similar:

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

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

Esto establecerá 'pacman' en el valor adecuado, la variable env PACMAN no se exporta, por lo que desaparecerá cuando finalice el script, y el uso de "comillas dobles" asegurará que se produzca la sustitución de la variable en la declaración del alias, No para cada invocación.

Yo uso un método similar:

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

Básicamente, configure el env var PACMAN, pruebe pacmatic en la ruta, si se encuentra, configure PACMAN, luego defina el alias.

Hmm, podrías optimizar un poco más ...

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

Taa Daa! Establezca en 'pacman' si PACMAN no está configurado o es nulo; de lo contrario, establezca el valor de PACMAN, establezca en pacmatic mediante la línea 'which'.


¿Por qué los alias solo funcionan para "fuentes interactivas"?
Mikel

Tienes razón en que, por defecto, bashno expande los alias en modo no interactivo, pero ¿cómo es eso lo mismo que "fuentes interactivas"?
Mikel

2

En zsh, puede agregar fácilmente un alias utilizando la aliasesmatriz asociativa:

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

En otros shells, debe usar la salida del aliascomando para obtener información sobre los alias existentes.

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

Si bien estoy ofreciendo esto como una posibilidad, seguiría usando una variable como ya lo sugieren otras respuestas. Es más claro, y se puede discriminar por el valor de la variable si desea configurar algunas cosas diferente en función de la cual uno de pacmatico pacmanestá en uso.

pacman==pacmatic 2>/dev/null || pacman=pacman
alias pacman='$pacman --color auto'

0

Una versión corta para el segundo alias sería:

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 "$@"
)

Los alias son para los pájaros.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.