Jak mogę „układać” aliasy powłoki?

12

W moim .profile(pochodzącym shz mojego trybu emulacji .zshrc) mam następujący fragment kodu:

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

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

Jednak drugi alias zawsze zastępuje pierwszy:

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

Jak mogę to zrobić, aby drugie przypisanie aliasu „dziedziczyło” pierwsze przypisanie, aby, jeśli /usr/bin/pacmaticistnieje, alias stał się pacmatic --color auto?

Nie jestem przeciwny używaniu funkcji zamiast aliasów, ale wolałbym, żeby logika nie była wykonywana przy każdym pacmanwywołaniu (chcę pacmaticsprawdzić raz, przy uruchomieniu powłoki, nie za każdym razem pacman). Wolałbym także shskrypt obsługiwany przez użytkownika, ale jeśli nie jest to możliwe, możesz użyć pełnej zshskładni.

(Tak, wiem, że można to łatwo rozwiązać, dołączając --color autodo pacmaticaliasu. Ale chcę to zrobić we właściwy sposób.)

Próbowałem Googling i przeglądałem strony, ale bezskutecznie.

strugee
źródło
Myślałem, że właściwą drogą jest używanie funkcji zamiast aliasów. Słyszałem, że są szybsze niż aliasy (przynajmniej w bash) i mogą łatwo do siebie dzwonić.
Wutaz

Odpowiedzi:

5

Powłoka aliaszachowuje się bardzo podobnie do a #define, tzn. Przedefiniowanie aliasu powłoki zastąpiłoby poprzednią.

Nie jestem pewien, jaka byłaby właściwa metoda TM , ale jednym z podejść byłoby użycie funkcji powłoki, która akceptuje parametry i użycie jej do utworzenia aliasu. Twój fragment kodu można przepisać jako:

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

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

 


Co więcej, nawet jeśli używasz różnych aliasów i próbujesz użyć jednego do zdefiniowania drugiego, nie zadziała, ponieważ aliasy nie są domyślnie rozwijane w trybie nieinteraktywnym. Musisz go włączyć, ustawiając expand_aliases:

shopt -s expand_aliases

Cytowanie z instrukcji:

   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).
diabelnie
źródło
wydaje się to być najbliższe temu, czego chcę, ale to nie działa. type pacmanzwraca pacman is an alias for pacman --color autozarówno w shtrybie emulacji , jak iw trybie macierzystym zsh. Wygląda jednak na to, że właśnie dokonana edycja jest tym, czego potrzebuję.
strugee
FWIW, odpowiednikiem zsh jest setopt aliases.
strugee
OP używa zsh. A i tak wydaje się, że powłoka jest interaktywna.
Mikel
6

Podstawienie aliasu jest wykonywane tylko podczas odczytywania wierszy ze źródeł interaktywnych. Zatem na drugi alias nie ma wpływu pierwszy, stąd dosłowne zastąpienie.

Być może coś podobnego:

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

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

Spowoduje to ustawienie właściwej wartości „pacman”, zmienna PACMAN env nie jest eksportowana, więc zniknie po zakończeniu skryptu, a użycie „podwójnych cudzysłowów” zapewni, że podstawienie zmiennej nastąpi przy deklaracji aliasu, nie dla każdego wywołania.

Używam podobnej metody:

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

Zasadniczo ustaw env var PACMAN, przetestuj ścieżkę pacmatic w ścieżce, jeśli znaleziono, ustaw PACMAN, a następnie zdefiniuj alias.

Hmm, możesz zoptymalizować trochę więcej ...

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

Taa Daa! Ustaw na „pacman”, jeśli PACMAN jest rozbrojony lub zerowy, w przeciwnym razie ustaw na wartość PACMAN, ustaw na pacmatic przez linię „która”.

lornix
źródło
Dlaczego aliasy działają tylko w przypadku „źródeł interaktywnych”?
Mikel
Masz rację, że domyślnie bashnie rozwija aliasów w trybie nieinteraktywnym, ale jak to się dzieje z „źródłami interaktywnymi”?
Mikel
2

W zsh możesz łatwo dołączyć do aliasu, używając aliasestablicy asocjacyjnej:

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

W innych powłokach musisz użyć danych wyjściowych aliaspolecenia, aby dowiedzieć się o istniejących aliasach.

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

Chociaż oferuję to jako możliwość, wybrałbym zmienną, jak już sugerują inne odpowiedzi. Jest jaśniejsze i można rozróżniać na podstawie wartości zmiennej, jeśli chcesz skonfigurować pewne rzeczy inaczej, na podstawie których jedna pacmaticlub pacmanjest w użyciu.

pacman==pacmatic 2>/dev/null || pacman=pacman
alias pacman='$pacman --color auto'
Gilles „SO- przestań być zły”
źródło
0

Krótka wersja drugiego aliasu to:

alias pacman=$PACMAN' --color auto'
Michael Durrant
źródło
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 "$@"
)

Aliasy są dla ptaków.

mikeserv
źródło