DryBones
DryBones

Reputation: 35

How to measure time of execution of each "sub-process" of a shell script

I'm running a program multiple times via script, but i need to get the time of execution of EACH time i run it. I'm trying to use the "time" function the same way as when i use it via terminal, but it doesn't really work. Here's my code with the "time" function inside the script:

#!/bin/sh
time ./tree < in_1.in > out_1.out
time ./tree < in_2.in > out_2.out
time ./tree < in_3.in > out_3.out
time ./tree < in_4.in > out_4.out
time ./tree < in_5.in > out_5.out
time ./tree < in_6.in > out_6.out
time ./tree < in_7.in > out_7.out
time ./tree < in_8.in > out_8.out
time ./tree < in_9.in > out_9.out
time ./tree < in_10.in > out_10.out

Note 1: Without the "time" before each line, the script runs perfectly. If possible, I'd like to put every recorded time into a new file, I tried using "echo", but haven't had any luck with it.

Note 2: Is there a way to make my script run with every file inside a directory, without specifically putting every and each one inside my script?

Upvotes: 1

Views: 914

Answers (1)

Michael Jaros
Michael Jaros

Reputation: 4681

There is no time command in the bourne shell (/bin/sh). Run your program with #!/bin/bash.

You can write recorded times into new files like this:

time ./tree < in_1.in > out_1.out 2> time_1.time

or if you want the time in the outfile:

time ./tree < in_1.in &> out_1.out

A very basic way of running your functionality for each of your .in files works with a loop and pathname expansion (using the * wildcard):

for filename in *.in
do
    time ./tree < "$filename" > "$( sed -e 's/in/out/g' <<< $filename )"
done

The expression "$( sed -e 's/in/out/g' <<< $filename )" is expanded to the result of replacing in with out in $filename. The double quotes around it prevent glob characters (*, ?) and newlines in filenames from breaking your code.

sed is a very common tool but the substitution can be written even shorter using Bash-only pattern substitution (note the double / after the first parameter which equals the g modifier in sed triggering substitution of all matches of the pattern):

time ./tree < "$filename" > "${filename//in/out}"

Another very common approach of executing commands for a set of files found in or under the working directory is using find -exec, which may be difficult in this case due to the redirections.

Upvotes: 1

Related Questions