问题描述
您如何在bash中编写函数来执行作为参数给出的命令,其中
How do you write a function in bash that executes the command that it is given as an argument, where
- 给定命令可能是别名
- 参数必须完全按照给定的方式传递;
换句话说,如何编写尽可能透明的包装函数。
In other words, how to write an as-transparent-as-possible wrapper function.
例如,包装函数的目标可以是在给定命令之前和之后设置当前目录,和/或设置环境变量或时间。只要给定的命令花费了很多时间,......作为一个简单的示例,我采用一个仅打印一行然后执行给定命令的函数。
The goal of the wrapper function could for example be to set the current directory before and after the given command, and/or set environment variables, or time how long the given command takes,... As a simple example here I take a function that just prints a line and then executes the given command.
第一次尝试:
function wrap1 {
echo Starting: "$@"
"$@"
}
您可以像 wrap1 echo hello
这样使用它。但是问题是您不能执行 alias myalias echo
然后调用 wrap1 myalias hello
:它无法解析别名。
You could use it like wrap1 echo hello
. But the problem is you cannot do alias myalias echo
and then call wrap1 myalias hello
: it wouldn't resolve the alias.
另一次尝试使用 eval
:
function wrap2 {
echo Starting: "$@"
eval "$@"
}
现在调用别名即可。但是问题在于它也评估了参数。例如, wrap2 echo \\a
仅打印 a
而不是 \ a
,因为参数被两次评估。
Now calling an alias works. But the problem is it evaluates the arguments too. For example wrap2 echo "\\a"
prints just a
instead of \a
because the arguments are evaluated twice.
shopt -s expand_aliases
不会
是否有一种方法可以评估像wrap2这样的别名,但仍然像wrap1那样直接传递参数?
Is there a way to both evaluate aliases like wrap2, but still pass on the arguments directly like wrap1?
推荐答案
您(嗯,我)可以使用printf%q来转义参数。
乍一看,使用printf转义,然后执行eval总是得到与直接传递参数相同的结果。
You (uh, I) can use printf %q to escape the arguments.At first sight, escaping with printf and then doing eval always gives the same result as passing the arguments directly.
wrap() {
echo Starting: "$@"
eval $(printf "%q " "$@")
}
这篇关于Bash函数调用命令作为参数给出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!