Bash变量扩展不能与时间命令结合使用

Bash variable expansion can't be combined with time command

我在 bash 中编写了一个小的 shell 脚本来测量使用 time 命令的几个可执行文件的速度。因为我想对几个不同的程序计时,为了避免重复我自己保存了时间命令和我想要的格式字符串并尝试使用变量扩展(以测试ls的性能为例):

#!/usr/bin/env bash

timer="/usr/bin/time -f 'elapsed time: %E' --"
$timer ls 1>/dev/null

time 命令应该使用 -- 将其选项(在本例中为格式字符串)与它应该计时的命令分开。但是,在此脚本中 time 坚持尝试执行我的格式字符串并失败

/usr/bin/time cannot run time:: No such file or directory
Command exited with non-zero status 127
'elapsed

但是,如果我将整个命令放在一行中,没有变量扩展,它会正确识别格式字符串并执行 ls:

#!/usr/bin/env bash

/usr/bin/time -f 'elapsed time: %E' -- ls 1>/dev/null

产生"elapsed time: 0:00.00"

我最后只是在每一行中输入了整个命令以将其发送到 运行,但我很好奇是否有人可以解释为什么变量扩展在这里不起作用。

您需要使用BASH数组来存储命令行:

timer=(/usr/bin/time -f 'elapsed time: %E' --)
"${timer[@]}" ls

$timer 中的数据按 $IFS(空格)拆分,并用作单独的参数。它没有扩展然后评估为 bash 代码。

您的命令 $timer ls 因此等同于:

"/usr/bin/time" "-f" "'elapsed time:" "%E'" "--" "ls"

在您的情况下,正确的方法是使用函数:

timer() {
  /usr/bin/time -f 'elapsed time: %E' -- "$@"
}
timer ls

PS:这个问题被shellcheck自动指出来了。