zsh:在函数内执行任意别名
zsh: execute arbitrary aliases inside a function
我正在尝试编写如下函数:
function myfunc() {
"$@"
}
实际函数还做了一些其他的事情,但关键是它环绕着任意输入命令。本质上,无论何时我们键入 myfunc <SOMETHING>
,对于 <SOMETHING>
.
的所有可能输入,结果应该与 <SOMETHING>
完全相同
虽然这会出现别名问题:
$ alias hello="echo hello"
$ myfunc hello
myfunc:1: command not found: hello
我尝试的另一种方法是使用 eval
:
$ function myfunc2() {
eval "$@"
}
$ $ myfunc2 hello
hello
$ myfunc2 hello '()'
(eval):1: defining function based on alias `hello'
(eval):1: parse error near `()'
$ hello '()'
hello ()
这在某些情况下有效,但在其他情况下无效。似乎 eval
最终得到了命令的不同视图,因为它已经经过了一些处理(我假设删除了单引号?)。
让我们看看这里实际发生了什么:
hello '()'
告诉 shell 不要解释 ()
(作为启动函数或其他任何东西),而是将文字字符串 ()
传递给 hello
.
myfunc2 hello '()'
告诉 shell 将字符串 hello
和 ()
传递给 myfunc2
.
eval "$@"
告诉 shell “评估这些字符串,就好像它们是在命令行上输入的一样”。
请注意,您传递给 myfunc2
的字符串是 hello
和 ()
, 不带引号 。引号只是转义字符,告诉 shell 不要将 ()
解释为字符串以外的任何其他内容。您还可以键入 \(\)
以将 ()
作为文字字符串传递(或 \(')'
或 '('\)
;它们都是等价的)。这些引号 and/or 反斜杠不是字符串本身的一部分。
因此,在 shell 扩展 "$@"
之后,eval "$@"
变为 eval hello ()
(没有 ()
周围的引号,因为它们不是传递给 myfunc2
) 的字符串,然后将其计算为好像 hello ()
(同样,不带引号)已在命令行中键入。
您需要做的是重新引用 myfunc2
:
的参数
% alias hello="echo hello"
% myfunc2 () {
eval "${(q)@}"
}
% myfunc2 hello '()'
hello ()
% myfunc2 hello \(\) \(')' '('\)
hello () () ()
%
我正在尝试编写如下函数:
function myfunc() {
"$@"
}
实际函数还做了一些其他的事情,但关键是它环绕着任意输入命令。本质上,无论何时我们键入 myfunc <SOMETHING>
,对于 <SOMETHING>
.
<SOMETHING>
完全相同
虽然这会出现别名问题:
$ alias hello="echo hello"
$ myfunc hello
myfunc:1: command not found: hello
我尝试的另一种方法是使用 eval
:
$ function myfunc2() {
eval "$@"
}
$ $ myfunc2 hello
hello
$ myfunc2 hello '()'
(eval):1: defining function based on alias `hello'
(eval):1: parse error near `()'
$ hello '()'
hello ()
这在某些情况下有效,但在其他情况下无效。似乎 eval
最终得到了命令的不同视图,因为它已经经过了一些处理(我假设删除了单引号?)。
让我们看看这里实际发生了什么:
hello '()'
告诉 shell 不要解释()
(作为启动函数或其他任何东西),而是将文字字符串()
传递给hello
.myfunc2 hello '()'
告诉 shell 将字符串hello
和()
传递给myfunc2
.eval "$@"
告诉 shell “评估这些字符串,就好像它们是在命令行上输入的一样”。
请注意,您传递给 myfunc2
的字符串是 hello
和 ()
, 不带引号 。引号只是转义字符,告诉 shell 不要将 ()
解释为字符串以外的任何其他内容。您还可以键入 \(\)
以将 ()
作为文字字符串传递(或 \(')'
或 '('\)
;它们都是等价的)。这些引号 and/or 反斜杠不是字符串本身的一部分。
因此,在 shell 扩展 "$@"
之后,eval "$@"
变为 eval hello ()
(没有 ()
周围的引号,因为它们不是传递给 myfunc2
) 的字符串,然后将其计算为好像 hello ()
(同样,不带引号)已在命令行中键入。
您需要做的是重新引用 myfunc2
:
% alias hello="echo hello"
% myfunc2 () {
eval "${(q)@}"
}
% myfunc2 hello '()'
hello ()
% myfunc2 hello \(\) \(')' '('\)
hello () () ()
%