Распечатать исполняемый псевдоним в zsh или bash

В настоящее время сценарий таков, я определил некоторые псевдонимы в .zshrc, например

alias gco='git checkout'
alias cdp='cd ..'

и много подобного. Мой вопрос: Как распечатать команду каждый раз, когда я набираю псевдоним и нажимаю клавишу ввода?

ex:

$> gco master
> Command: git checkout master
> Git process ...

как-то так, если решение также работает в bash, было бы лучше! Спасибо!


person Transparency    schedule 09.08.2013    source источник
comment
Это почти дубликат stackoverflow.com/questions/ 9299402/echo-all-aliases-in-zsh.   -  person Jon Schneider    schedule 21.01.2020
comment
В zsh вы можете просто ввести .., и он будет работать как cd ... На самом деле это работает для любого пути к каталогу, а не только для ... (Или, может быть, это поведение специфично для моей конфигурации)   -  person Lucas Alonso    schedule 22.07.2021


Ответы (1)


Это аккуратный вопрос. Мы можем сделать это, определив пару функций для расширения псевдонимов, а затем использовать хук 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
comment
ТАК ответы не могут быть лучше, чем этот. - person Eric Jiang; 28.01.2019
comment
Находить такие ответы одно удовольствие! Потрясающая работа! - person equiman; 21.01.2021
comment
Я только что обнаружил ошибку с этим псевдонимом alias obp="explorer.exe \".\\build\"", он работает хорошо, но показывает команду в консоли, например eplorer.exe "uild", и в пути отсутствует `.\`. - person equiman; 21.01.2021