I'd like to log execution time of my commands. Something like this:

#!/usr/bin/env bash
echo "$@" >> /tmp/times
exec 3>&2
(/usr/bin/time -f "%e" "$@" 2>&3) 2>>/tmp/times

The problem is that time spawns child process that polluted standard error. Can this be done without this side effect?

1 Answer 1


If you use /usr/bin/time, then the only way to send the timed process's stderr and the time information to different channels is to tell the time utility to do it. You can't do it with redirections in the shell that calls time because the timed process's stderr and the output from time itself are sent to the same file descriptor.

The time utility that you're using (based on your use of -f, it's GNU coreutils) has an option -o to tell it to write to a different file, and -a to append to this file. This option also exists on FreeBSD and macOS.

echo "$@" >>/tmp/times
exec time -f %e -a -o /tmp/times -- "$@"

Alternatively, you can use the shell keyword (in shells that have it, which includes bash, ksh and zsh). With the keyword, you can control where the time information goes through redirection, because you can specify a redirection as part of the timed process.

echo "$@" >>/tmp/times
{ time "$@" 2>&3; } 3>&2 2>>/tmp/times
  • After a quick test, only the secon works for me. GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu) under Funtoo-Linux. Commented Nov 3, 2017 at 8:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .