这对我有用了~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 bar
or 1=foo
or之后运行argv[1]=foo
,就会变成:
alias | grep foo git
在文件中查找,忽略其标准grep
输入。foo
git
在这里,您想要 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 replacement
to更改alias token=replacement
为搬起石头砸自己的脚,因为这意味着你不能为包含=
字符的标记添加别名。 POSIX 指定了该接口sh
并zsh
复制了它,但是在 中zsh
,您也可以aliases['=']=uname
在那里解决限制(如果您想'='
用 替换uname
)。