How do I simplify bash's 'eval “$TIME $BIN_FILE $BIN_OPTS &> $LOG_FILE”' and keep it working?

Deadly 提交于 2019-12-08 08:12:55

问题


I'm updating a bash script which serves as a program testing tool. Previously, I had this line in a script working perfectly ($BIN_FILE is set to a relative path to the binary being tested):

$BIN_FILE $BIN_OPTS &> $LOG_FILE

Then I've decided to add some "performance measurements":

time $BIN_FILE $BIN_OPTS &> $LOG_FILE"

This worked perfectly as well, but when running many tests at once, script's output was too crowded with all those "real, user, system". Now I'm passing a second parameter to the script, which causes $TIME variable to have value 'time' assigned to it. However,

$TIME $BIN_FILE $BIN_OPTS &> $LOG_FILE

just doesn't work. The only working option seems to be

eval "$TIME $BIN_FILE $BIN_OPTS &> $LOG_FILE"

but it's ugly.

Why doesn't

$TIME $BIN_FILE $BIN_OPTS &> $LOG_FILE

work? Is there a nicer-looking solution, then the one with eval?

Also, regarding portability - should I use bash's internal 'time', or call GNU /usr/bin/time?


回答1:


time is a reserved word in bash. It must be written explicitly because it is parsed before parsing the "simple commands", and therefore before variable substitutions. For example, you cannot use builtin time in this way:

cat long-file | time sort

It has to be:

time cat long-file | sort

and here bash will measure time spend by whole pipeline.

GNU time is a simple binary, so it can be used in the way you mean it... and it can be used in the middle of a pipeline. But it is not always installed, so I guess you'd better use builtin.

I guess you want to omit time in some specific cases and because of that you want variable substitution. If so, you can go with GNU time, eval or some kind of if..fi structure, but you definitely cannot use builtin the way you wanted.

If you want to be more portable, you should use its -p option to get the same output under different implementations. See f.e. OpenGroup's time description. Then whatever implementation you choose, it should behave the same way (as long as it is POSIX-compliant).




回答2:


You may find it helpful to use a shorter format for the output of time:

$ /usr/bin/time -f "Real %E" sleep 1
Real 0:01.02
$ TIMEFORMAT="Real %R"
$ time sleep 1        # Bash builtin
Real 1.027

The output of either version of time can be further customized (less so for the Bash builtin).



来源:https://stackoverflow.com/questions/1767329/how-do-i-simplify-bashs-eval-time-bin-file-bin-opts-log-file-and-kee

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!