Это аккуратный вопрос. Мы можем сделать это, определив пару функций для расширения псевдонимов, а затем использовать хук preexec
для запуска функций перед их выполнением.
Я взял ответ здесь.
1. Оценить все псевдонимы
_aliases="$(alias -Lr 2>/dev/null || alias)"
alias_for() {
[[ $1 =~ '[[:punct:]]' ]] && return
local found="$( echo "$_aliases" | sed -nE "/^alias ${1}='?(.+)/s//\\1/p" )"
[[ -n $found ]] && echo "${found%\'}"
}
Во-первых, сохраните все псевдонимы в переменной. alias -r
печатает все псевдонимы regular
(не глобальные и не суффиксные), а alias -L
печатает их "способом, подходящим для использования в сценариях запуска". Функция alias_for()
выполняет некоторую очистку, удаляя кавычки и помещая alias
перед строками. Когда мы делаем echo ${_aliases}
, мы получаем что-то вроде этого:
alias history='fc -l 1'
alias ls='ls -F -G'
alias lsdf='ls -1l ~/.*(@)'
alias mv='mv -v'
Сравните это с выводом alias
:
history='fc -l 1'
ls='ls -F -G'
lsdf='ls -1l ~/.*(@)'
mv='mv -v'
2. Функция проверки наличия псевдонима.
Если был введен псевдоним, теперь мы можем его обнаружить и, таким образом, распечатать:
expand_command_line() {
[[ $# -eq 0 ]] && return # If there's no input, return. Else...
local found_alias="$(alias_for $1)" # Check if there's an alias for the comand.
if [[ -n $found_alias ]]; then # If there was
echo ${found_alias} # Print it.
fi
}
3. Заставить это запускаться каждый раз, когда вводится команда
Для этого идеально подходит функция preexec
. Это функция, которая:
Выполняется сразу после того, как команда была прочитана и готова к выполнению. Если механизм истории активен (и строка не была удалена из буфера истории), в качестве первого аргумента передается введенная пользователем строка, в противном случае это пустая строка. Фактическая команда, которая будет выполняться (включая расширенные псевдонимы), передается в двух различных формах: второй аргумент представляет собой однострочную версию команды ограниченного размера (с опущенными такими элементами, как тела функций); третий аргумент содержит полный текст, который выполняется.
из Руководства по zsh, глава 9.
Обратите внимание, мы могли бы просто использовать функцию preeexec для отображения того, что выполняется.
Чтобы добавить нашу функцию в preexec, мы используем хук используя этот пример:
autoload -U add-zsh-hook # Load the zsh hook module.
add-zsh-hook preexec expand_command_line # Adds the hook
Чтобы удалить крючок позже, мы можем использовать:
# add-zsh-hook -d preexec expand_command_line # Remove it for this hook.
Моя оболочка
Вот как выглядит моя оболочка, когда я ее запускаю:
$ 1
cd -
$ rake
bundle exec rake
^C
$ chmod
usage: chmod [-fhv] [-R [-H | -L | -P]] [-a | +a | =a [i][# [ n]]] mode|entry file ...
chmod [-fhv] [-R [-H | -L | -P]] [-E | -C | -N | -i | -I] file ...
$ git lg1
fatal: Not a git repository (or any of the parent directories): .git
Ошибки (или «особенности»)
Как видно из примера с моей оболочкой, когда запускается команда без псевдонима (например, chmod
), полная команда не отображается. Когда запускается команда с псевдонимом (например, 1
или rake
), отображается полная команда.
При запуске псевдонима git
(например, git lg1
) псевдоним git
не раскрывается. Если вы посмотрите на мою первую ссылку, полный пример использует расширение псевдонима git
— вы должны взять его и изменить, если git псевдонимы жизненно важны для вас.
person
simont
schedule
22.08.2013
..
, и он будет работать какcd ..
. На самом деле это работает для любого пути к каталогу, а не только для..
. (Или, может быть, это поведение специфично для моей конфигурации) - person Lucas Alonso   schedule 22.07.2021