Come posso "impilare" gli alias di shell?


12

Nel mio .profile(proveniente shdalla mia modalità di emulazione dal mio .zshrc) ho il seguente frammento:

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

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

Tuttavia, il secondo alias sostituisce sempre il primo:

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

Come posso fare in modo che il secondo incarico alias "erediti" il primo incarico, in modo che se /usr/bin/pacmaticesiste, l'alias diventa pacmatic --color auto?

Non sono contrario all'utilizzo di funzioni anziché di alias, ma lo preferirei se la logica non fosse eseguita ogni volta che pacmanviene invocata (voglio pacmaticcontrollarla una volta, all'avvio della shell, non ogni volta che pacmanviene eseguita). Preferirei anche uno shscript portabile, ma se ciò non fosse possibile, puoi utilizzare la zshsintassi completa .

(Sì, sono consapevole che questo potrebbe essere facilmente risolto aggiungendo --color autol' pacmaticalias. Ma voglio farlo nel modo giusto ™.)

Ho provato a cercare su Google le pagine man, ma senza risultati.


Ho pensato che il modo giusto fosse usare le funzioni invece degli alias. Ho sentito che sono più veloci degli alias (almeno in bash) e possono chiamarsi facilmente.
Wutaz,

Risposte:


5

Una shell aliassi comporta in modo simile a una #define, ovvero ridefinire un alias di shell avrebbe la precedenza su quella precedente.

Non sono sicuro di quale sarebbe il modo giusto TM , ma un approccio sarebbe quello di utilizzare una funzione shell che accetta parametri e usarlo per creare un alias. Lo snippet di codice potrebbe essere riscritto come:

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

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

 


Inoltre, anche se si stessero utilizzando alias diversi e si stesse tentando di utilizzarne uno per definire l'altro, non funzionerebbe in quanto gli alias non vengono espansi in modalità non interattiva per impostazione predefinita. È necessario abilitarlo impostando expand_aliases:

shopt -s expand_aliases

Citando dal manuale:

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

questo sembra essere il più vicino a quello che voglio, ma non funziona. type pacmanritorna pacman is an alias for pacman --color auto, sia in shmodalità emulazione che in zshmodalità nativa . tuttavia, sembra che la modifica che hai appena effettuato sia ciò di cui ho bisogno.
strugee,

FWIW, l'equivalente zsh è setopt aliases.
strugee

OP sta usando zsh. E la shell sembra essere comunque interattiva.
Mikel,

6

La sostituzione dell'alias viene eseguita solo durante la lettura di righe da fonti interattive. Quindi il secondo alias non è influenzato dal primo, quindi la sostituzione letterale.

Forse qualcosa di simile:

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

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

Questo imposterà "pacman" sul valore corretto, la variabile env PACMAN non verrà esportata, quindi andrà via al termine dello script e l'uso di "virgolette doppie" assicurerà che la sostituzione della variabile avvenga alla dichiarazione dell'alias, non per ogni invocazione.

Uso un metodo simile:

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

Fondamentalmente, impostare env var PACMAN, test per pacmatic in path, se trovato, impostare PACMAN, quindi definire alias.

Hmm, potresti ottimizzare un po 'di più ...

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

Taa Daa! Impostato su 'pacman' se PACMAN è disinserito o nullo, altrimenti impostato su valore di PACMAN, impostato su pacmatic dalla linea 'quale'.


Perché gli alias dovrebbero funzionare solo per "fonti interattive"?
Mikel,

Hai ragione che, per impostazione predefinita, bashnon espande gli alias in modalità non interattiva, ma come è uguale a "fonti interattive"?
Mikel,

2

In zsh, puoi facilmente aggiungere un alias usando l' aliasesarray associativo:

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

In altre shell, è necessario utilizzare l'output del aliascomando per scoprire gli alias esistenti.

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

Mentre sto offrendo questo come una possibilità, vorrei usare una variabile come già suggerito da altre risposte. È più chiaro e puoi discriminare il valore della variabile se desideri configurare alcune cose in modo diverso in base a quale pacmatico pacmanè in uso.

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

0

Una versione breve per il 2 ° alias sarebbe:

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

Gli alias sono per gli uccelli.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.