Roninski
Roninski

Reputation: 23

How can I output from /usr/bin/time to a file at the right location within execution?

I'm writing a script to mass time a quicksort execution with different input files and flags, and output them in a formatted way in an external file. Here's part of the script so you can understand the context:

echo $file 
echo "Naive Pivot"
count=1
while [ $count -lt 4 ]
do
    echo "Run $count"
    count=$(($count+1))
    time ./quicksort -pn -so < $file
    echo
done

I've tried redirecting it normally (from stdout)

time ./quicksort -pn -so < $file > timing.txt

and attempted to redirect from stderr (though I may be doing that wrong).

time ./quicksort -pn -so < $file 2 >> timing.txt

I've also tried

/usr/bin/time -p -o timing.txt -a ./quicksort -pn -so < $file

And running the script with the standard stderr output setup like this

./testData.sh > timing.txt 2 > timing.txt

However, they both appends ALL timing data at the END of the file, instead of between the output of the echo commands I'd put before and after it. So whilst everything comes out in order in the command line, when I try to run my script directing output to a file, all the echo.

I've exhausted my personal knowledge and need help. How do I get the time command (time or /usr/bin/time) to properly output into my file at the location relative to their execution? Thanks in advance.

Upvotes: 2

Views: 4099

Answers (1)

rici
rici

Reputation: 241861

time is a bash builtin. /usr/bin/time is a simple command-line program. They require different treatment.

First, what I think you want to do is redirect both stderr and stdout to a file. In bash, you can do that with &>file (or &>>file if you want to append), or you can use the more general solution: >file 2>&1. (See "Redirecting Standard Output and Standard Error" in man bash).

That will work fine with /usr/bin/time, which is an ordinary program which creates a subshell to run the program described by its arguments, and then outputs timing information to stderr.

But in the case of the bash builtin time, which is actually syntactically part of the command line, that won't work because the command line which is timed includes the redirects; the timing information is sent to the unredirected stderr of bash itself. To get what you want, you need to run the entire timed pipeline in a subshell:

(time ./quicksort -pn -so < $file) &> timing.txt

Upvotes: 5

Related Questions