这是可能的,但很难看:
for action in status start stop restart; do
eval "$action() { systemctl $action \"\$@\"; }"
done
与涉及 的任何事情一样eval
,这很难正确处理。所做的事情eval
是两次解析命令,并在第二次解析时执行它。“嗯?” 我听你说?好吧,问题是通常$variable
函数定义中的引用不会立即扩展,而是在函数执行时。因此,当您的循环运行时(action
设置为“状态”):
$action() {
systemctl $action $*
done
它扩展了第一个引用$action
而不是第二个引用,给出了这个:
status() {
systemctl $action $*
done
相反,您希望两个引用都$action
立即展开。但是您不希望$*
立即扩展引用,因为那样它将使用脚本的参数,而不是在运行时提供给函数的参数。实际上,您根本不想要$*
,因为它在某些情况下会破坏论点;改为使用"$@"
。
所以你需要一种方法来立即扩展一些变量/参数引用,并将一些推迟到以后。eval
给你。最棘手的事情是您可能需要两个级别的引用/转义(一个用于第一次解析传递,一个用于第二次解析),并且您需要使用这些级别来控制哪些变量/参数引用立即展开,哪些稍后展开。
当它运行时(action
设置为“状态”):
eval "$action() { systemctl $action \"\$@\"; }"
...它进行解析传递,扩展未转义的变量引用并删除一定程度的引用和转义,给出:
status() { systemctl status "$@"; }
...这就是你想要的。