Timeout doesn't work, please help me

#!/bin/sh
trap "cleanup" TERM
timeout=5
mainpid=$$
cleanup()
{
    echo "at $i interupt"
    kill -9 0 
}


watchdog()
{
    sleep $1
}


(watchdog $timeout && kill -TERM $mainpid) & 

run_test()
{
for i in `seq 1 100`
do
        sleep 1 
       # i=$((i+1))
    echo "$i,contiuing"
done
}

run_test |tee -a x.log 

it doesn't interrupt by the TERM, and I want to print where to interrupt by 'echo $i' can you help me to get where is interrupt

I removed i=$((i+1)) and I got:

1,contiuing
2,contiuing
3,contiuing
4,contiuing
at 5 interupt
Killed: 9

What result did you get and what did you expect to get?

after I removed i=$((i+1)), it doesn't work like your side

I want get
after 5s (timeout=5), the script will be stopped and with it's subprocess stopped too, and alos get where it stopped, here is "echo "at $i interupt" to tell where it stopped

OK so what shell are you using, what OS, how do you execute your script and can you post the output of your script.

I'm on "Ubuntu 12.04.4 LTS \n \l" without terminate running this script

lyang001@lyang001-OptiPlex-9010:~/nehalem_workdir$ echo $SHELL
/bin/bash

root@lyang001-OptiPlex-9010:/home/lyang001/del# ./zz.sh 
1,contiuing
2,contiuing
3,contiuing
4,contiuing
5,contiuing
6,contiuing
7,contiuing
8,contiuing
9,contiuing
10,contiuing
11,contiuing
12,contiuing
13,contiuing
14,contiuing
......
......

---------- Post updated 07-07-15 at 03:26 AM ---------- Previous update was 07-06-15 at 11:30 PM ----------

if I remove the '|tee x.log', it works, but I really need it

Move the

mainpid=$$

and its use

(watchdog $timeout && kill -TERM $mainpid)

into the function

run_test(){
}

it doesn't work. nothing changes

Try:

run_test >(tee -a x.log)

You will need to change 1st line to #!/bin/bash to avoid sh-compatibie mode

things get better, but I find if I change the "sleep 1" to "sleep 100", after 5s, it doesn't kill the "sleep 100", and looks it doesn't kill the mainpid too, so the cleanup doesn't execute.

BTW, can you explain the usage you offered, thanks

Bash and dash not work but ksh93 can do it.
Problem is pipe = how to do it.
Difference is how to think about pipe: like you think it = "programmer way" = ksh (88+93) or works it like it has defined, own process = bash, posix, dash, ... = you kill the pipe 1st process.

command line is process to kill (=ksh) or current process kill (bourne shell, bash, dash,...).

The best example is pipe and read. I don't say which works correctly, because both works as they has planned. But I like more David Korn way to think about it. It use shared mem between piped subprocess = sub process create variable and I can use it in the parent process.

# ksh only 
echo a b c | read var1 var2
echo $var1 : $var2

All other shells you need to use io redirection, then it's same process, works also in ksh:

read var1 var2 <<EOF
$(echo a b c)
EOF
echo $var1 : $var2

after I use

run_test >(tee -a x.log)

it works, but if I add sleep 100s in function run_test, it doesn't kill the "sleep 100" after 5s(timeout)

anyone can help me ?