No such file or directory when executing /usr/bin/time

I'm building my own android rom. In order to build it, I need to run

mka -j8 bacon

However, I wanted to measure the time it took to build it, so I used

/usr/bin/time -f "User\t%U\nSys\t%S\nReal\t%E\nCPU\t%P" mka -j8 bacon

This won't run, because it's saying

/usr/bin/time: cannot run mka: No such file or directory

Any help how to work around this, it's appreciated! I'm running xubuntu.

Edit:

For some reason, using make instead of mka does work, however using mka is better.

/usr/bin/time -f "User\t%U\nSys\t%S\nReal\t%E\nCPU\t%P" make -j8 bacon

Edit 2: from the cyanogenmod website

Invoking $ source build/envsetup.sh or $ . build/envsetup.sh from your shell runs the envsetup.sh script in the build directory. envsetup.sh adds many functions to the build environment, the most important of which are listed below.

source build/evnsetup.sh is the command I run before executing time. One of those added functions by evnsetup.sh is mka, is it possible to call this from within the time command?

Edit 3: Output of type mka

$ type mka
mka is a function
mka () 
{ 
    case `uname -s` in 
        Darwin)
            make -j `sysctl hw.ncpu|cut -d" " -f2` "$@"
        ;;
        *)
            schedtool -B -n 1 -e ionice -n 1 make -j$(cat /proc/cpuinfo | grep "^processor" | wc -l) "$@"
        ;;
    esac
}

Solution 1:

The problem is that mka is a bash function exported by your script and not an executable (as opposed to make), so /usr/bin/time doesn't find it, as it looks for an executable.

There are two possible solutions.

First, note that there is a difference between the bash built-in function time, and the executable /usr/bin/time. These are different commands, which take different parameters and generate different output:

$ time sleep 1

real    0m1.001s
user    0m0.000s
sys     0m0.001s

$ /usr/bin/time sleep 1
0.00user 0.00system 0:01.00elapsed 0%CPU (0avgtext+0avgdata 664maxresident)k
0inputs+0outputs (0major+215minor)pagefaults 0swaps

Type help time to get help for the bash built-in time. Type man time to get help for the executable /usr/bin/time.

The first solution uses time, whereas the second solution uses /usr/bin/time.

First solution: using the bash built-in function time

The bash built-in function time is aware of declared bash functions, and you can immediately use it to measure the time of such functions.

$ foo() {
    sleep 1;
    echo "Hello World"
  }
$ time foo
Hello World

real    0m1.002s
user    0m0.000s
sys     0m0.001s

In your case, the following command should work:

$ time mka -j8 bacon

This would be my preferred way. However, it may not generate exactly the output you want. In particular, it does not measure or print CPU usage.

Second solution: using the executable /usr/bin/time

You cannot directly measure the time of a built-in bash function using /usr/bin/time (as far as I know), but what you can do is measure the time of the /bin/bash executable executing that bash function. This is a little hacky, and it generates a little overhead as you are launching an extra instance of bash. But this overhead may be negligible when faced with a function that takes minutes to compute, so it may still suit your needs better.

To be able to launch the /bin/bash executable on a bash function, we have to export the function first.

$ foo() {
    sleep 1;
    echo "Hello World"
  }
$ export -f foo
$ echo foo | /usr/bin/time /bin/bash
Hello World
0.00user 0.00system 0:01.00elapsed 0%CPU (0avgtext+0avgdata 1476maxresident)k
0inputs+0outputs (0major+707minor)pagefaults 0swaps

Hence, in your case, to be able to use /usr/bin/time and generate the output format you want, you could proceed as follows:

$ export -f mka
$ echo 'mka -j8 bacon' | /usr/bin/time -f "User\t%U\nSys\t%S\nReal\t%E\nCPU\t%P" /bin/bash