##Kudos
It's good to see appropriate quoting and correct use of "$@" in these shell scripts. Although the samples are short, it's still good to see nice readable code.
##Problems with the first approach
- All the output of the command is sent to
/dev/stderr; it's not possible to pipe the output into another command, or to separate the output and error streams. - The exit status of the command is lost, so you can't use this function as part of a conditional (
if,while,&&,||, ...). - Only a single command can be timed, rather than a full pipeline.
##Problems with the second approach
- The exit status of the command is lost.
- Only a single command can be timed (but that's always the case with an external
timecommand, and why it's a built-in in Bash).
An improvement
You can retain the exit status when using GNU time, by using a process substitution as the output file:
function run_time {
command time --quiet \
--format '%e' \
--output >(tee -a run_time.txt >&2) \
"${@}"
}
###Notes
- I've also used the
commandkeyword to find the externaltimewithout hard-coding its path. You may or may not choose to follow this course. - I've sent the time result to standard error, for consistency with the command and built-in (note that the built-in outputs to the shell's standard error, not that of the pipeline it's timing).
#Alternative using built-in
function run_time {
local TIMEFORMAT='%R'
{ { time "$@" 2>&3; } 2> >(tee -a run_time.txt >&2); } 3>&2
}
That's a bit hard to follow, so let's unpick it from the inside:
*
{ time "$@" 2>&3; }
The command's standard output is unchanged (stream 1), but its stderr is redirected to stream 3; time's output will be on stream 2.
*
{...} 2> >(tee ... >&2)
The time output is redirected to the tee command; it writes to the file and to the enclosing stream 2 (the function's standard error stream).
*
{ ... } 3>2
The saved standard error stream of the timed command is diverted back to the function's standard error.
This allows independent redirection of the timed command's standard output and standard error (plus timing results). The function's error status is that of the timed command.
One disadvantage is that it doesn't wait for the process substitution to exit before the function returns, so tee's output may occur unexpectedly late (e.g. after Bash has shown the next command prompt, in an interactive shell).