trap not work in program with a subshell environment

From: Michael Wang (mwang@unixlabplus.com)
Date: 04/24/03


From: mwang@unixlabplus.com (Michael Wang)
Date: Wed, 23 Apr 2003 22:26:27 GMT

Here is my sample program:

--
#!/usr/dt/bin/dtksh
{
{
{
(
    PID= unset PID; (( PID = 0 ))
    function handle_signal {
      (( PID == 0 )) || {
        kill $PID
        print "killed $PID."
      }
      print "inside trap."
      exit 1
    }
    trap handle_signal INT TERM
    /bin/sleep 1200 &
    PID=$!
    wait $PID
)
print "exit_code=$?"
} 9>&- | tee -a /dev/null >&9
} 2>&1 | tee -a /dev/null >&2
} 9>&1
print "I am here."
--
And here is the process tree. Please note the program
"1.ksh" appears twice in the process tree.
      7204  /usr/dt/bin/dtksh ./1.ksh
        7206  tee -a /dev/null
        7205  tee -a /dev/null
          7207  /usr/dt/bin/dtksh ./1.ksh
            7208  /bin/sleep 1200
If I kill the second "1.ksh" (PID: 7207), then I get the intended
behavior. However if I kill the first "1.ksh" (PID: 7204), then
the program terminates without trapping.
And this is the problem, because the first process is the process that
will be killed by the parent process, which does not know the second
process.
If I move the function handle_signal, and the trap outside the subshell
environment (...):
--
#!/usr/dt/bin/dtksh
    PID= unset PID; (( PID = 0 ))
    function handle_signal {
      (( PID == 0 )) || {
        kill $PID
        print "killed $PID."
      }
      print "inside trap."
      exit 1
    }
    trap handle_signal INT TERM
{
{
{
(
    /bin/sleep 1200 &
    PID=$!
    wait $PID
)
print "exit_code=$?"
} 9>&- | tee -a /dev/null >&9
} 2>&1 | tee -a /dev/null >&2
} 9>&1
print "I am here."
--
and I got a process tree:
      8947  /usr/dt/bin/dtksh ./2.ksh
        8950  tee -a /dev/null
        8948  tee -a /dev/null
          8949  /usr/dt/bin/dtksh ./2.ksh
            8951  /bin/sleep 1200
The problem is no matter which process (8947 or 8949) I kill,
the program does not terminate.
However if I get rid of the complicated subshell environment:
--
#!/usr/dt/bin/dtksh
    PID= unset PID; (( PID = 0 ))
    function handle_signal {
      (( PID == 0 )) || {
        kill $PID
        print "killed $PID."
      }
      print "inside trap."
      exit 1
    }
    trap handle_signal INT TERM
    /bin/sleep 1200 &
    PID=$!
    wait $PID
print "I am here."
--
I get a process tree shown below. Please note 
the process named "3.ksh" appear only once.
      9417  /usr/dt/bin/dtksh ./3.ksh
        9418  /bin/sleep 1200
And if I kill the process, it gives the expected behaviour.
But the problem is I need the complicated subshell environment
so that stdout and stderr are duplicated to a file. And my goal
is with this subshell environment, trap is used when I kill the
first process, and ideally trap is also used when I kill the
second process, or any process in the tree, as I can not predict
how user uses "ps", "grep", and "kill".
Thanks.
-- 
Michael Wang * http://www.unixlabplus.com/ * mwang@unixlabplus.com


Relevant Pages

  • Re: sh: Terminating children upon SIGTERM
    ... "$pid" with $pid being the pid of a process that just terminated ... The second race condition is that $prog1_or_2 might already have been spawned, but $pid not yet set when a SIGTERM comes in, so the trap would not kill the spawned process. ...
    (comp.unix.shell)
  • Re: Periodic Fedora 9 system hangs with jumpy mouse
    ... kill -TERM pid ... to do with graphics card and driver. ...
    (Fedora)
  • RE: threads in perl
    ... Instead of xterm I tried to invoke some other script: ... How can I kill exec after it was started in different thread? ... But threads all share the same pid, ... When life conspires against you, and no longer floats your boat, Don't waste your time with crying, just get on your back and float. ...
    (perl.beginners)
  • Re: Killing a process tree? - 1 attachment
    ... Well, you could use ps to get process and parent process pid, ... match subprocess to parent process, and kill in reverse order. ...
    (alt.os.linux)
  • Re: [opensuse] Help Killling Process
    ... will not die nor will it display anything. ... I remember from the 'old days' that there is a cli command to ... identify a process id and another one to kill a process. ... This will give you a listing of the processes and their pid' although ...
    (SuSE)