16
votes

I need to write the time taken to execute this command in a txt file:

time ./program.exe

How can I do in bash script?

I try with >> time.txt but that doesn't work (the output does not go to file and does go to the screen).

4

4 Answers

24
votes

Getting time in bash to write to a file is hard work. It is a bash built-in command. (On Mac OS X, there's an external command, /usr/bin/time, that does a similar job but with a different output format and less recalcitrance.)

You need to use:

(time ./program.exe) 2> time.txt

It writes to standard error (hence the 2> notation). However, if you don't use the sub-shell (the parentheses), it doesn't work; the output still comes to the screen.


Alternatively, and without a sub-shell, you can use:

{ time ./program.exe; } 2> time.txt

Note the space after the open brace and the semi-colon; both are necessary on a single line. The braces must appear where a command could appear, and must be standalone symbols. (If you struggle hard enough, you'll come up with ...;}|something or ...;}2>&1. Both of these identify the brace as a standalone symbol, though. If you try ...;}xyz, the shell will (probably) fail to find a command called }xyz, though.)


I need to run more command in more terminal. If I do this:

 xterm -xrm '*hold: true' -e (time ./Program.exe) >> time.exe & sleep 2

it doesn't work and tells me Syntax error: "(" unexpected. How do I fix this?

You would need to do something like:

xterm -xrm '*hold: true' -e sh -c "(time ./Program.exe) 2> time.txt & sleep 2"

The key change is to run the shell with the script coming from the argument to the -c option; you can replace sh with /bin/bash or an equivalent name. That should get around any 'Syntax error' issues. I'm not quite sure what triggers that error, though, so there may be a simpler and better way to deal with it. It's also conceivable that xterm's -e option only takes a single string argument, in which case, I suppose you'd use:

xterm -xrm '*hold: true' -e 'sh -c "(time ./Program.exe) 2> time.txt & sleep 2"'

You can manual bash xterm as well as I can.

I'm not sure why you run the timed program in background mode, but that's your problem, not mine. Similarly, the sleep 2 is not obviously necessary if the hold: true keeps the terminal open.

0
votes

It's not easy to redirect the output of the bash builtin time.

One solution is to use the external time program:

/bin/time --append -o time.txt ./program.exe

(on most systems it's a GNU program, so use info time rather than man to get its documentation).

0
votes

time_elapsed=(time sh -c "./program.exe") 2>&1 | grep "real" | awk '{print $(NF)}' echo time_elapsed > file.txt This command should give you the exact time consumed in bash in a desired file..

You can also redirect this to a file usng 2 > file.txt as explained in another reply.

0
votes

Just enclose the command to time in a { .. }:

{ time ./program.exe; } 2>&1

Of course, the output of builtin time goes to stderr, thus the needed redirection 2>&1.

Then, it may appear to be tricky to capture the output, let's use a second { .. } to read the command more easily, this works:

{ { time ./program.exe; } 2>&1; } >> time.txt              # This works.

However, the correct construct should simply have the capture reversed, as this:

{ time ./program.exe; } >> time.txt  2>&1;                 # Correct.

To close any possible output from the command, redirect it's output to /dev/null, as this:

{ time ./program.exe >/dev/null 2>&1; } >> time.txt 2>&1   # Better.

And, as now there is only output on stderr, we could simply capture just it:

{ time ./program.exe >/dev/null 2>&1; } 2>> time.txt       # Best.

The output from ./program should be redirected, or it may well end inside time.txt.