用于 grep 所有别名的 ZSH 别名停止工作

用于 grep 所有别名的 ZSH 别名停止工作

这对我有用了~8年:

$ alias al='alias | grep $1'

例子:

$ al git
clean='git clean -xfde'
echo_git_root='echo "$(git rev-parse --show-toplevel || echo .)"'
# etc.

我可以调用像al git,它会显示我所有的 git 别名。

然而现在我得到:

$ al git
grep: git: No such file or directory

看来别名没有被替换:

$ alias al
al='alias | grep $1'

当然,当我运行naked命令(绕过别名)时它工作正常:

$ alias | grep git
clean='git clean -xfde'
echo_git_root='echo "$(git rev-parse --show-toplevel || echo .)"'
# etc.

我试过了:

  • al='alias | /usr/bin/grep $1'
  • al='alias | \grep $1'
  • al='alias | grep ''$1'''
  • al='alias | grep \\'$1\\''

此时我已经没有主意了!

我最近从 MacOS Monterey 升级到 Ventura,我不确定之前的 ZSH 版本是什么,但现在是 5.9。我不确定这是否相关,但这是我的系统最近唯一的更改。

答案1

别名不接受参数,它们只是用其他文本替换文本。它们是一种非常糟糕的编程结构形式。它们来自没有功能的 csh。

alias al='alias | grep $1'

只是说al令牌将替换为alias | grep $1在命令位置中找到该令牌的任何位置,因此:

al git

被替换为:

alias | grep $1 git

然后将其解释为 shell 代码。

如果$1为空或未设置,则与以下内容相同:

alias | grep git

但如果在set foo baror 1=fooor之后运行argv[1]=foo,就会变成:

alias | grep foo git

在文件中查找,忽略其标准grep输入。foogit

在这里,您想要 Bourne 风格:

al() alias | grep "$@"

或 csh-style²:

alias al='alias | grep'

1 嗯,在csh别名的来源中,您可以使用一些涉及历史扩展的技巧,使其看起来像别名可以接受参数,但这些技巧不会在类似 Korn 的 shell 中发挥作用。

² 那么,在 中csh,那必须是alias al 'alias | grep';由于某种原因,David Korn 在 80 年代为 ksh 复制该功能时决定将语法从alias token replacementto更改alias token=replacement为搬起石头砸自己的脚,因为这意味着你不能为包含=字符的标记添加别名。 POSIX 指定了该接口shzsh复制了它,但是在 中zsh,您也可以aliases['=']=uname在那里解决限制(如果您想'='用 替换uname)。

相关内容