4

Is there a way to measure the time spent in every single command within a bash file? Hence, put time in front of every command. The quantity of commands is unknown right now, as I intend to use this time measure for future bash scripts, too. And also worth mentioning is that I intend to only run simple bash scripts having command1, command2, command3, ... etc. Hence, no complex higher logic scripts.

Lets say I have a bash file similar to this one:

#!/bin/bash

mv /path/to/file /other/path/
cd /other/path/
tar -xzf /other/path/file

Is there a way to get some output similar to this?

 6.553s   mv /path/to/file /other/path/
 0.057s   cd /other/path/
19.088s   tar -xzf /other/path/file

I know that with time I can get the time spent of a single command. But I am looking for a solution for measuring the time of every command itself.

  • 2
    So you put time in front of every command. – Rinzwind Jul 7 '18 at 16:15
  • 1
    What Socrates suggested is to place "time" before every line in your script in order to have the time duration for every command. You could use "sed" to automatically prepend "time" to each line, but it might not be worth the effort if you have only a few lines in your script. – vanadium Jul 7 '18 at 16:25
  • 1
    Probably the closest you will get is something like this: How to debug a bash script and get execution time per command – steeldriver Jul 7 '18 at 16:53
  • 1
    The basic solution: to add the text string according to my answer to every line is not the best one, probably it will fail in a more advanced script, because the syntax will be destroyed (depending on what syntax you use). It is better to identify what are external commands, executable programs and shell buittin commands and other shellscripts and add the text string according to my answer in front of those. Maybe you (or someone else) can create a script, that helps you identify those commands and add the text string only to the relevant lines. – sudodus Jul 12 '18 at 9:20
  • 1
    I did some testing, and timing of shell builtin commands don't work this way. In your example cd is affected. On the other hand it is very fast (and most shell builtin commands are rather fast). – sudodus Jul 12 '18 at 10:03
6

You can use /usr/bin/time with the option -f like the following example. Preceed each command in your shellscript with /usr/bin/time -f "%E %C"

$ /usr/bin/time -f "%E %C" sleep 2.34
0:02.34 sleep 2.34

See man time for more details.

Example:

I made a small script, that can work to modify a simple shellscript by identifying commands, that can be tested with /usr/bin/time. Let us use the name time2script.

#!/bin/bash

string='/usr/bin/time -f "%E %C"'

while IFS= read -r line
do
 cmd=$(<<< "$line" sed -e 's/ *//'|cut -d ' ' -f1)
 command=$(which "$cmd")
 if [ "$command" != "" ]
 then
  printf '%s %s\n' "$string" "$line"
 else
  printf '%s\n' "$line"
 fi
done < "$1"

Using time2script on the example in the edited question:

$ ./time2script socrates1
#!/bin/bash

/usr/bin/time -f "%E %C" mv /path/to/file /other/path/
cd /other/path/
/usr/bin/time -f "%E %C" tar -xzf /other/path/file

Redirect to create a modified shellscript,

./time2script socrates1 > socrates1-timing
| improve this answer | |
2

This is the naive approach. It has a few points of failure*, so I don't necessarily recommend using it, just wanted to mention it.

#!/bin/bash
# Time each command in another Bash script.

script="$1"

# Skip blank lines and comments.
grep -vE "^\s*($|#)" "$script" |
    while IFS= read -r line
do
    echo "$line"
    time eval "$line"
done

Example script foo.sh:

#/bin/bash
true
sleep 2.34

Example run:

$ bash naive_timer.sh foo.sh
true

real    0m0.000s
user    0m0.000s
sys     0m0.000s
sleep 2.34

real    0m2.342s
user    0m0.000s
sys     0m0.000s

* E.g. eval will choke on multi-line commands, like function declarations, array declarations, heredocs, even multi-line quotes. And commands that rely on the value of $0 may not work.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.