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

标签 alias zsh zshrc

目前的情况是,我在 .zshrc 中定义了一些别名像

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

和很多这样的。
我的问题是每次我输入别名并按回车时如何打印出命令?

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

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

最佳答案

这是一个巧妙的问题。我们可以通过定义几个函数来扩展别名,然后使用 preexec钩子(Hook)在我们执行函数之前运行它们。

我从 here 得到了答案.

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功能非常适合这个。这是一个功能:

Executed just after a command has been read and is about to be executed. If the history mechanism is active (and the line was not discarded from the history buffer), the string that the user typed is passed as the first argument, otherwise it is an empty string. The actual command that will be executed (including expanded aliases) is passed in two different forms: the second argument is a single-line, size-limited version of the command (with things like function bodies elided); the third argument contains the full text that is being executed.



from the zsh Manual, chapter 9 .

注意,我们可能只使用 preeexec 函数来显示正在运行的内容。

要将我们的函数添加到 preexec,我们使用 Hook using this example :
autoload -U add-zsh-hook        # Load the zsh hook module. 
add-zsh-hook preexec expand_command_line      # Adds the hook 

要稍后删除钩子(Hook),我们可以使用:
# add-zsh-hook -d preexec expand_command_line # Remove it for this hook.

我的壳

这是我运行 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

错误(或“功能”)

正如我们从我的 shell 示例中看到的,当运行没有别名的命令时(如 chmod ),不会显示完整的命令。运行别名命令(如 1rake )时,将显示完整的命令。

当一个 git运行别名(例如 git lg1), git别名未展开 .如果你看我的first link , 完整的例子确实使用 git别名扩展 - 如果 git 别名对您至关重要,您应该接受并修改。

关于alias - 在 zsh 或 bash 中打印执行的别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18143307/

相关文章:

java - 使用 Java EWS API 检索 "Alias"

mysql - 从此 SQL 查询中删除变量(子查询帮助)

sql - 别名上的 JOIN 语句 - SQL Server

bash - 如何从 shell 获取一组子进程(在 macOS 中)的所有父进程名称?

macos - 在 Zsh 中登录时无法启动受 '0700' 保护的程序

ZSH auto_vim(像 auto_cd)

子域的子域别名

rvm 不使用 zsh 设置默认的 ruby

zshrc - zsh 提示符中的时钟