尽管an alias
是执行此操作的一种方法,但也可以做到eval
这一点-只是您并不想eval
执行eval
命令声明,而是想要执行命令。
我喜欢alias
es-我一直都在使用'em,但是我更喜欢函数-特别是它们处理参数的能力,并且不必像alias
es 所要求的那样在命令位置扩展它们。
所以我想也许您也想尝试一下:
_time() if set -- "${IFS+IFS=\$2;}" "$IFS" "$@" && IFS='
'; then set -- "$1" "$2" "$*"; unset IFS
eval "$1 $TIME ${3#"$1"?"$2"?}"
fi
该$IFS
位主要是关于$*
。同样重要的是,( subshell bit )
它也是shell扩展的结果,因此为了将参数扩展为我使用的可分析字符串"$*"
(eval
"$@"
顺便说一句,除非您确定所有args都可以在空格上连接,否则请不要)。args in之间的分隔定界符"$*"
是中的第一个字节$IFS
,因此如果不确定其值可能会很危险。所以函数保存$IFS
,将其设置为一个\n
ewline足够长set ... "$*"
成"$3"
,unset
原来是这样的话,如果它以前有一个复位其值。
这是一个小演示:
TIME='set -x; time'
_time \( 'echo "$(echo any number of subshells)"' \
'command -V time' \
'hash time' \
\) 'set +x'
您会看到我在其中的值中放置了两个命令$TIME
-任何数字都可以-甚至没有数字-但请确保将其转义并正确引用-并且to的参数也是如此_time()
。它们在执行时都将被合并为单个命令字符串-但是每个arg都有其自己的\n
ewline,因此它们可以相对容易地散布。否则,您可以将它们全部\n
合并在一起,如果需要的话,还可以将它们分开,用粗线,分号或“随您便”。只要确保单个参数代表一个命令,您在调用该命令时便会在脚本中放自己的一行。\(
,例如可以,只要最终紧随其后即可\)
。基本上是正常的东西。
当eval
获取上述代码片段时,它看起来像:
+ eval 'IFS=$2;set -x; time (
echo "$(echo any number of subshells)"
command -V time
hash time
)
set +x'
而且,其结果看起来像...
输出值
+++ echo any number of subshells
++ echo 'any number of subshells'
any number of subshells
++ command -V time
time is a shell keyword
++ hash time
bash: hash: time: not found
real 0m0.003s
user 0m0.000s
sys 0m0.000s
++ set +x
该hash
错误表明我没有/usr/bin/time
安装(因为我没有安装),command
让我们知道正在运行哪个时间。尾随set +x
是在 time
(可能)之后执行的另一个命令-在eval
输入任何内容时,请务必小心输入命令。