如何有条件地通过“时间”传递子shell?

Der*_*ler 9 shell bash quoting time

我有一个 Vagrant box 的设置脚本,我曾经在其中使用time. 现在我想有条件地启用或禁用时间测量。

例如,以前的一行看起来像:

time (apt-get update > /tmp/last.log 2>&1)
Run Code Online (Sandbox Code Playgroud)

现在我想我可以简单地做这样的事情:

MEASURE_TIME=true
[[ $MEASURE_TIME = true ]] && TIME="time --format=%e" || TIME=""

$TIME (apt-get update > /tmp/last.log 2>&1)
Run Code Online (Sandbox Code Playgroud)

但这行不通:

syntax error near unexpected token `apt-get'
`$TIME (apt-get update > /tmp/last.log 2>&1)'
Run Code Online (Sandbox Code Playgroud)

这里有什么问题?

Sté*_*las 13

为了能够计时子shell,您需要time 关键字,而不是命令。

time关键字,语言的一部分,从字面上输入时才承认为和作为命令的第一个字(和在的情况下ksh93,那么下一个令牌不具有启动-)。甚至输入"time"也不会起作用$TIME(并且会被视为对time命令的调用)。

您可以在此处使用别名,这些别名在执行另一轮解析之前进行了扩展(这样可以让 shell 识别该time关键字):

shopt -s expand_aliases
alias time_or_not=
TIMEFORMAT=%E

MEASURE_TIME=true
[[ $MEASURE_TIME = true ]] && alias time_or_not=time

time_or_not (apt-get update > /tmp/last.log 2>&1)
Run Code Online (Sandbox Code Playgroud)

time 关键字不采取选项(除了-pbash),但格式可以与设定TIMEFORMAT在变量bash。(该shopt部分也是bash特定的,其他外壳通常不需要)。