![zsh:一个前缀函数,运行该行的其余部分,没有别名扩展](https://linux22.com/image/144324/zsh%EF%BC%9A%E4%B8%80%E4%B8%AA%E5%89%8D%E7%BC%80%E5%87%BD%E6%95%B0%EF%BC%8C%E8%BF%90%E8%A1%8C%E8%AF%A5%E8%A1%8C%E7%9A%84%E5%85%B6%E4%BD%99%E9%83%A8%E5%88%86%EF%BC%8C%E6%B2%A1%E6%9C%89%E5%88%AB%E5%90%8D%E6%89%A9%E5%B1%95.png)
我在想:
function noalias() {
setopt localoptions noexpandalias
"$@"
}
但我不知道最后一行应该是什么。eval "${*:q}"
?eval "$@"
?eval "${@:q}"
?"${@:q}"
?${@:q}
?$@
? (你能解释一下它们之间的区别吗?)
答案1
别名在很早的阶段就被扩展了,在一个简单的命令被理解之前,更不用说执行一个函数了,所以这是行不通的。
在读取和解析命令行之前,您需要noaliases
(expandalias
是bash
选项) 选项生效。
但是,如果您只想禁用普通别名,即在使用 定义的命令位置中扩展的别名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进行切换。