Shell – Using time on bash functions (not commands)

functionshell-scripttime

How can one measure individual calls to bash functions from inside the bash file.

I have a program that I call using the command

eclipse -b col_solve.pl -e "myPred"

This call outputs some information, the last of which is SUCCESS or FAIL.
I am writing a script that is called on a bunch of files in a directory, and for each of these files, outputs

  • The name
  • The status (SUCCESS or FAIL)
  • and the (user) time it took to execute .

This is the code that I know works:

I use this to get the status (retrieving the last word in the output):

stat=
get_stat ( ){
    stat=$(awk '{print $NF}' <<< $1);
}

I use this to call the program :

run_eclipse_on ( ){
    get_stat "$(eclipse -b col_solve.pl -e "run(\"$1\")" )";
}

The problematic code is the following:

for i in `ls $1` ;  #where $1 is the directory containing the files
do
    tps=$(/usr/bin/time -f %U      \ #to get just the user time
         [run_eclipse_on $1/$i] ); # HERE it is! 
    echo $i::$stat::::$tps;  # gives, for ex: file_name::SUCCESS::::0.20
done

The culprit line is the one where the function is called. I tried surrounding it with `, {, [, $(, ' and ". Nothing worked…

Is it even possible…?

Best Answer

Use the time keyword instead of the external command. Using the keyword allows you to run time on any shell command, including function calls, not just on running a program. You can control the output format to some extent through the TIMEFORMAT variable.

TIMEFORMAT=%2U
time run_eclipse_on …
echo "$i::$stat"

The time output gets printed on its own line, though. Bash allows a trick: you can change TIMEFORMAT during the command, so you can stuff more things in there.

time { run_eclipse_on …; TIMEFORMAT="${i//%/%%}::${stat//%/%%}::%2U"; }

The output from time is printed to standard error. If you need it on standard output, just redirect with 2>&1. That will also redirect whatever the command printed on stderr, however. To preserve stderr, you can do some file descriptor shuffling.

{ time { {
      run_eclipse_on …;
      TIMEFORMAT=$stat::%2U;
    } 2>&3; } 2>&1; } 3>&2
Related Question