How to run "time" on a function in zsh

This works:

time ls -l

This does not work

f() { ls -l }
time f

No time output is printed in the second case. Why?


Solution 1:

@John1024 gave you the answer for bash. I try to answer the zsh tag...

You get the timing statistics, if you spawn a subshell for your function:

% zsh
% f() { sleep 1 }
% time f
% time (f)
( f; )  0.00s user 0.05s system 4% cpu 1.061 total
% time sleep 1
sleep 1  0.00s user 0.03s system 2% cpu 1.045 total

This adds a little overhead, but as you can see from this (non-faked ;)) example, it's probably insignificant.

Solution 2:

You have tagged this with both bash and zsh. This answer applies to bash.

This is an error in bash:

f() { ls -l }

What works instead is:

f() { ls -l ; }

With that new definition of f, the time command works.

Under bash, when grouping commands together in braces, the last command must be followed by a semicolon or a newline. This is documented under "Compound Commands" in man bash.

(I would test this solution under zsh but I don't currently have it installed. But, as per this SO post, the solution under zsh might be to run f in a subshell. Update: See @mpy's answer for zsh.)