Why don't kill the script after 5s?

# watchdog process 
mainpid=$$ 
(sleep 5; kill $mainpid) & 
watchdogpid=$! 
sleep 100 
kill $watchdogpid

The sleep isn't be killed, I want the script to be killed

---------- Post updated at 03:03 AM ---------- Previous update was at 12:04 AM ----------

I just modify the format of my script

Shells (man bash (linux), man ksh (linux), etc) do not propagate signals to non-builtin commands. To illustrate this a bit better, I replaced the sleep in your script with a script tasker

#! /usr/bin/perl

$\ = ' ';
$| = 1;
$s = 10;

sub handler {printf "\ncaught SIG\%s\n", shift @_; $s = 0; }

$SIG{INT}  = \&handler;
$SIG{TERM} = \&handler;

while ($s--) { print $s; sleep(1); }
printf "\nexit\n";

Nothing fancy, it counts down from 9 with one second delays. So your script is now (with some man echo (linux)s):

# watchdog process 
mainpid=$$ 
echo mainpid $$
trap : TERM
( sleep 5; echo killing $mainpid; kill $mainpid ) & 
watchdogpid=$! 
echo watcher $!
tasker
echo killing $watchdogpid
kill $watchdogpid

And when run:

$ yangleiold
mainpid 22277
watcher 22278
9 8 7 6 5 4 killing 22277
3 2 1 0 exit
killing 22278
yangleiold: line 10: kill: (22278) - No such process

What you need to do is have the watchdog kill the subprocess directly:

# watchdog process 

tasker &
pid=$!

sleep ${1:-5}
echo Killing $pid
kill $pid

Which runs as:

$ yangleinew
9 8 7 6 5 Killing 32765
caught SIGTERM
exit

Now if the task finishes first, the script will still sleep for the full interval:

$ yangleinew 20
9 8 7 6 5 4 3 2 1 0 exit
Killing 22361
x: line 8: kill: (22361) - No such process

Hope this helps.