Differences between revisions 2 and 3
Revision 2 as of 2007-06-14 20:51:30
Size: 1496
Editor: GreyCat
Comment: expand. and correct. my god, correct that wrong stuff!
Revision 3 as of 2007-08-30 03:05:44
Size: 1643
Editor: GreyCat
Comment: clean up and clarify
Deletions are marked like this. Additions are marked like this.
Line 13: Line 13:
 * File Redirection
{{{
   bash -c "time ls" 2>time.output
   ( time ls ) 2>time.output
   { time ls; } 2>time.output
 * File redirection:
 {{{
   bash -c "time ls" 2>time.output # Explicit, but inefficient.
   ( time ls ) 2>time.output  # Slightly more efficient.
   { time ls; } 2>time.output  # Most efficient.
Line 19: Line 20:
   { time some command >stdout 2>stderr; } 2>time.output
}}}
   { time some command >stdout 2>stderr; } 2>time.output}}}
Line 22: Line 22:
 * Variable Redirection
{{{
 * Command substitution:
 {{{
Line 25: Line 25:
   foo=$( { time ls; } 2>&1 ) # More efficient version.
Line 33: Line 34:
   foo=$( { time bar 2>&4; } 2>&1 1>&3) # Captures time only.
   exec 3>&- 4>&-
}}}
   foo=$( { time bar 1>&3 2>&4; } 2>&1 ) # Captures time only.
   exec 3>&- 4>&-}}}

Anchor(faq32)

How can I redirect the output of 'time' to a variable or file?

Bash's time keyword uses special trickery, so that you can do things like

   time find ... | xargs ...

and get the execution time of the entire pipeline, rather than just the simple command at the start of the pipe. (This is different from the behavior of the external command time(1), for obvious reasons.)

Because of this, people who want to redirect time's output often encounter difficulty figuring out where all the file descriptors are going. It's not as hard as most people think, though -- the trick is to call time in a different shell or block, and redirect stderr of that shell or block (which will contain time's results). If you need to redirect the actual command's stdout or stderr, you do that inside the inner shell/block. For example:

  • File redirection:
       bash -c "time ls" 2>time.output      # Explicit, but inefficient.
       ( time ls ) 2>time.output            # Slightly more efficient.
       { time ls; } 2>time.output           # Most efficient.
    
       # The general case:
       { time some command >stdout 2>stderr; } 2>time.output
  • Command substitution:
       foo=$( bash -c "time ls" 2>&1 )       # Captures *everything*.
       foo=$( { time ls; } 2>&1 )            # More efficient version.
    
       # Keep stdout unmolested.
       exec 3>&1
       foo=$( { time bar 1>&3; } 2>&1 )      # Captures stderr and time.
       exec 3>&-
    
       # Keep both stdout and stderr unmolested.
       exec 3>&1 4>&2
       foo=$( { time bar 1>&3 2>&4; } 2>&1 )  # Captures time only.
       exec 3>&- 4>&-

BashFAQ/032 (last edited 2018-07-26 21:28:38 by GreyCat)