目前的情况是,我在 .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
),不会显示完整的命令。运行别名命令(如 1
或 rake
)时,将显示完整的命令。当一个
git
运行别名(例如 git lg1
), git
别名未展开 .如果你看我的first link , 完整的例子确实使用 git
别名扩展 - 如果 git 别名对您至关重要,您应该接受并修改。
关于alias - 在 zsh 或 bash 中打印执行的别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18143307/