Как я могу «сложить» псевдонимы оболочки?

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-портативный скрипт, но если это невозможно, вы можете использовать полный zshсинтаксис.

(Да, я знаю , что это может быть легко решена путем добавления --color autoк pacmaticпсевдониму. Но я хочу сделать это правильный путь ™) .

Я пробовал гуглить и просматривать страницы, но безрезультатно.

strugee
источник
Я думал, что правильным способом было бы использовать функции вместо псевдонимов. Я слышал, что они быстрее, чем псевдонимы (по крайней мере, в bash), и они могут легко вызывать друг друга.
Утаз

Ответы:

5

Оболочка aliasведет себя очень похоже на a #define, то есть переопределение псевдонима оболочки переопределит предыдущий.

Я не уверен, что будет Right Way 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).
devnull
источник
это кажется самым близким к тому, что я хочу, но это не работает. type pacmanвозвращает pacman is an alias for pacman --color autoкак в shрежиме эмуляции, так и в собственном zshрежиме. однако, похоже, что редактирование, которое вы только что сделали, это то, что мне нужно.
Струге
FWIW, то ЗШ эквивалент setopt aliases.
стружка
ОП использует zsh. И оболочка в любом случае выглядит интерактивной.
Микель
6

Подстановка псевдонимов выполняется только при чтении строк из интерактивных источников. Таким образом, второй псевдоним не зависит от первого, отсюда и буквальная замена.

Возможно, что-то похожее:

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

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

Это установит 'pacman' на правильное значение, переменная env PACMAN не будет экспортирована, поэтому она исчезнет, ​​когда скрипт завершится, а использование двойных кавычек обеспечит замену переменной при объявлении псевдонима, не для каждого вызова.

Я использую аналогичный метод:

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» в строке «which».

lornix
источник
Почему псевдонимы работают только для «интерактивных источников»?
Микель
Вы правы в том, что по умолчанию 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

Короткая версия для второго псевдонима будет выглядеть так:

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

Псевдонимы для птиц.

mikeserv
источник