zsh:一个前缀函数,运行该行的其余部分,没有别名扩展

zsh:一个前缀函数,运行该行的其余部分,没有别名扩展

我在想:

function noalias() { 
  setopt localoptions noexpandalias
  "$@"
 }

但我不知道最后一行应该是什么。eval "${*:q}"eval "$@"eval "${@:q}""${@:q}"${@:q}$@? (你能解释一下它们之间的区别吗?)

答案1

别名在很早的阶段就被扩展了,在一个简单的命令被理解之前,更不用说执行一个函数了,所以这是行不通的。

在读取和解析命令行之前,您需要noaliases(expandaliasbash选项) 选项生效。

但是,如果您只想禁用普通别名,即在使用 定义的命令位置中扩展的别名alias foo=bar,请执行以下操作:

noalias() "$@"

就足够了,因为如果有别名cmd,它就不会在以下位置扩展:

noalias cmd args

因为cmd不在指挥位置。

那是行不通的全球的别名(用 、 设置的别名alias -g,例如alias -g args=foo展开任何 shell单词无论他们是否处于指挥位置)。

即使你这样做了:

noalias() { 
  setopt localoptions noaliases
  eval "$@"
}

并使用以下命令调用您的命令:

noalias 'cmd args'

这并不是万无一失的,例如:

alias -g "'cmd arg'=gotcha"

或者

alias -g noalias=gotcha

你需要跑

set +o expandalias

在读取命令之前。不过,您可以使用键绑定来完成此操作:

toggle-aliases() {
  if [[ -o aliases ]]; then
    set +o aliases
  else
    set -o aliases
  fi
  zle -I
}
zle -N toggle-aliases
bindkey '\eA' toggle-aliases
PS1='[aliases $options[aliases]] '$PS1

然后按Alt+ Shift+A进行切换。

相关内容