It may be the way you have in shell script --
`timeout 2 ./run.sh`
-- you are using command substitution, so as long as the command has not finished execution, substitution cannot be done, because the output is not there...this may explain the output you are seeing.
Try this to see a similar outcome....
echo "hello `sleep 2 &`"
Another script of interest --
$ cat y.sh
echo "hi"
sleep 2 &
echo "bye"
sleep 2 &
Run using
echo "hello `sh y.sh`"
$time sh y.sh
hi
bye
real 0m0.006s
user 0m0.000s
sys 0m0.004s
$time echo "hello `sh y.sh`"
hello hi
bye
real 0m2.008s
user 0m0.004s
sys 0m0.000s
This page explains more about the relationship between background process and file descriptor. Basicly:
Background (better: forked) processes inherit the file descriptors, and Running a command in backticks means to collect its stdout until its stdout is closed