Як я можу "складати" псевдоніми оболонки?


12

У моєму .profile(джерело в shрежимі емуляції з мого .zshrc) у мене є такий фрагмент:

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

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

Однак другий псевдонім завжди перекриває перший:

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

Як я можу зробити так, щоб друге призначення псевдоніма "успадковувало" перше призначення, так що якщо воно /usr/bin/pacmaticіснує, псевдонім стає pacmatic --color auto?

Я не проти використання функцій замість псевдонімів, але я вважаю за краще, якщо логіка не виконується кожен раз, коли pacmanвикликається (я хочу pacmaticперевірити один раз, при запуску оболонки, не кожен раз, коли pacmanвона запускається). Я також віддаю перевагу shсценарію -portable, але якщо це неможливо, ви можете використовувати повний zshсинтаксис.

(Так, я знаю , що це може бути легко вирішена шляхом додавання --color autoдо pacmaticпсевдоніму. Але я хочу зробити це правильний шлях ™) .

Я спробував гуглінг і переглядав манпажі, але безрезультатно.


Я подумав, що Правильний шлях - використовувати функції замість псевдонімів. Я чув, що вони швидші, ніж псевдоніми (принаймні, в bash), і вони можуть легко дзвонити один одному.
Wutaz

Відповіді:


5

Оболонка aliasповодиться досить аналогічно а #define, тобто повторне визначення псевдоніму оболонки замінить попередній.

Я не впевнений, що було б в правильному напрямку TM , але одним із підходів було б використання функції оболонки, яка приймає параметри і використовує її для створення псевдоніма. Ваш фрагмент коду може бути переписаний як:

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

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

 


Більше того, навіть якщо ви використовували різні псевдоніми і намагалися використовувати одне для визначення іншого, воно не буде працювати, оскільки псевдоніми не розширюються в неінтерактивному режимі за замовчуванням. Увімкнути це потрібно, встановивши expand_aliases:

shopt -s expand_aliases

Цитуючи посібник:

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

це здається найближчим до того, що я хочу, але це не працює. type pacmanповертається pacman is an alias for pacman --color autoяк в shрежимі емуляції, так і в рідному zshрежимі. однак, схоже, що саме мені потрібна редакція, яку ви зробили.
strugee

FWIW, zsh еквівалент є setopt aliases.
strugee

ОП використовує zsh. І оболонка все одно є інтерактивною.
Мікель

6

Заміна псевдоніму виконується лише при читанні рядків з інтерактивних джерел. Тож другий псевдонім не впливає на перший, отже, буквальна заміна.

Можливо, щось подібне:

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

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

Це встановить 'pacman' на належне значення, змінна PACMAN env не експортується, тому вона відійде, коли сценарій закінчиться, а використання «подвійних лапок» забезпечить, що підміна за змінною відбудеться при оголошенні псевдоніму, не для кожного виклику.

Я використовую подібний метод:

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

В основному, встановіть env var PACMAN, тест на pacmatic у шляху, якщо його знайдено, встановіть PACMAN, а потім визначте псевдонім.

Гм, ви можете трохи більше оптимізувати ...

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

Таа Даа! Встановіть значення "pacman", якщо PACMAN не встановлений або недійсний, інакше встановіть значення PACMAN, встановлене на pacmatic за допомогою рядка "what".


Чому псевдоніми працюють лише для "інтерактивних джерел"?
Мікель

Ви праві, що за замовчуванням bashпсевдоніми не розширюються в неінтерактивному режимі, але як це те саме, що і "інтерактивні джерела"?
Мікель

2

У zsh ви можете легко додати псевдонім за допомогою aliasesасоціативного масиву:

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

В інших оболонках вам потрібно використовувати висновок aliasкоманди, щоб дізнатися про існуючі псевдоніми.

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

Хоча я пропоную це як можливість, я б пішов із використанням змінної, як уже запропоновано іншими відповідями. Це зрозуміліше, і ви можете розрізнити значення змінної, якщо хочете налаштувати деякі речі по-іншому, залежно від того, який з них використовується pacmaticабо pacmanвикористовується.

pacman==pacmatic 2>/dev/null || pacman=pacman
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 "$@"
)

Псевдоніми для птахів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.