How to run time on multiple commands AND write the time output to file?

Use sh -c 'commands' as the command, e.g.:

/usr/bin/time --output=outtime -p sh -c 'echo "a"; echo "b"'

Not the correct answer but very related to the question.
Get timing statistics for multiple programs combined parentheses are required. Separate commands with semicolons ; or &&, if command2 should only be run, when command1 exited without error:

time ( command1 ; command2 )

time ( command1 && command2 )

Try this:

% (time ( { echas z; echo 2 } 2>&3 ) ) 3>&2 2>timeoutput
zsh: command not found: echas
% cat timeoutput                                
( { echas z; echo 2; } 2>&3; )  0.00s user 0.00s system 0% cpu 0.004 total


First, we have to find a way to redirect the output of time. Since time is a shell builtin, it takes the full command line as the command to be measured, including redirections. Thus,

% time whatever 2>timeoutput
whatever 2> timeoutput  0.00s user 0.00s system 0% cpu 0.018 total
% cat timeoutput 
zsh: command not found: whatever

[Note: janos's comment implies this is not the case for bash.] We can achieve the redirection of time's output by running time in a subshell and then redirecting the output of that subshell.

% (time whatever) 2> timeoutput
% cat timeoutput 
zsh: command not found: whatever
whatever  0.00s user 0.00s system 0% cpu 0.018 total

Now we have successfully redirected the output of time, but its output is mixed with the error output of the command we are measuring. To separate the two, we use an additional file descriptor.

On the "outside" we have

% (time ... ) 3>&2 2>timeout

This means: whatever is written to file descriptor 3, will be output to the same place file descriptor 2 (standard error) is outputting now (the terminal). And then we redirect standard error to the file timeout.

So now we have: everything written to stdout and fd 3 will go to the terminal, and everything written to stderr will go to the file. What's left is to redirect the measured command's stderr to fd 3.

% (time whatever 2>&3) 3>&2 2>timeout

Now, to make time measure more than one command, we need to run them in an(other!) subshell (inside parentheses). And to redirect the error output of all of them to fd 3, we need to group them inside curly brackets.

So, finally, we arrive at:

% (time ( { whatever; ls } 2>&3 ) ) 3>&2 2>timeoutput

That's it.