在zsh或bash中打印执行的别名

Tra*_*ncy 8 alias zsh zshrc

该方案目前,我已经定义了一些别名.zshrc

alias gco='git checkout'
alias cdp='cd ..'
Run Code Online (Sandbox Code Playgroud)

还有那么多.我的问题是每次输入别名时如何打印命令并按回车键?

例如:

$> gco master
> Command: git checkout master
> Git process ...
Run Code Online (Sandbox Code Playgroud)

类似的东西,如果解决方案也适用于bash会更好!谢谢!

sim*_*ont 8

这是一个很好的问题.我们可以通过定义几个函数来扩展别名,然后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%\'}"
}
Run Code Online (Sandbox Code Playgroud)

首先,将所有别名存储在变量中.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'
Run Code Online (Sandbox Code Playgroud)

将此与以下输出进行比较alias:

history='fc -l 1'
ls='ls -F -G'
lsdf='ls -1l ~/.*(@)'
mv='mv -v'
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

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 
Run Code Online (Sandbox Code Playgroud)

要稍后删除钩子,我们可以使用:

# add-zsh-hook -d preexec expand_command_line # Remove it for this hook.
Run Code Online (Sandbox Code Playgroud)

我的壳

这是我运行时shell的样子:

$ 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
Run Code Online (Sandbox Code Playgroud)

错误(或"功能")

从我的shell示例中可以看出,当运行没有别名的命令(如chmod)时,不会显示完整命令.运行别名命令(如1rake)时,将显示完整命令.

当一个git别名运行(git lg1,例如),所述git别名没有展开.如果你查看我的第一个链接,那么完整的例子确实使用了git别名扩展 - 你应该接受并修改git别名对你来说至关重要.

  • 所以答案再好不过了。 (2认同)