Operating System - HP-UX
1753287 Members
5412 Online
108792 Solutions
New Discussion юеВ

traps, sleeping procs, shell scripting, oh my

 
SOLVED
Go to solution
Jim Johnson_8
Occasional Contributor

traps, sleeping procs, shell scripting, oh my

My shell is sh.
How do I send a signal to my sleeping shell script that gets trapped immediately? It seems that the process has to wait until the sleep is finished before anything can be trapped. The exception seems to be kill -1, which the process traps immediately, but it also hangsup and the process is no longer running.
Here is my example script:
#!/usr/bin/sh
trap 'echo "THIS IS COOL"' 1 2 3 15
while :
do
echo HELLO
sleep 30
echo WORLD
done
exit 0

Run this script in the background. Send kill -2, -3, -15 signals won't happen until it wakes up. Sending a kill -1 seems to execute the trap, but the process dies as well.
1) So how to I send a signal that gets trapped immediately even if sleeping?
2) If it has to be a 1, then how do I trap a 1 and still have the process continue to run.

I want to avoid other scripting langs like perl, and I want to avoid having to kill the sleep process that is also generated. I have searched the forums and see several posts about traps, but nobody ever talks about sleeping processes.
I see Clay has a good script here:
http://forums.itrc.hp.com/cm/QuestionAnswer/1,,0x01fbc6af36b7d5118ff10090279cd0f9,00.html
But it too dies if you send it a kill -1.

2.5) Why are these scripts dying, when that goes against what we are telling it to do with the trap?

Thanks,
Jim
8 REPLIES 8
Jordan Bean
Honored Contributor
Solution

Re: traps, sleeping procs, shell scripting, oh my


Jim, work with this:

#!/usr/bin/sh
set -m
trap 'echo CHLD' CHLD
trap 'echo EXIT' EXIT
trap 'echo ERR' ERR
trap 'echo TRAP' HUP INT QUIT TERM
trap 'echo DONE; kill -ALRM %1; exit 0' USR1
echo $$ > $0.pid
while :
do
echo tick
sleep 5 &
wait
echo $?
done
echo tock


I'm no expert on this, so I'll decline to comment on how this works.

Ollie R
Respected Contributor

Re: traps, sleeping procs, shell scripting, oh my

Hi Jim,

I don't see any way to wake the script up from a sleep simply because the "sleep" command itself will have its own process ID. You have to kill or wake up the "sleep" process itself to get the script to continue.

A way to achieve the required result is to use another language where the "sleep" is part of the parent process, then the "sleep" can be woken up by sending a "kill -14" to the parent process.

For example, with perl:

#!/usr/contrib/bin/perl
{
print "HELLO\n";
sleep (30) ;
print "WORLD\n" ;
redo ;
}

If you run this in background and send a kill -14 to the background process it will continue the loop.

I hope this helps,

Ollie.
To err is human but to not award points is unforgivable
Ollie R
Respected Contributor

Re: traps, sleeping procs, shell scripting, oh my

Hi Jim,

I've been experimenting in case you aren't too hot on perl scripting! 8O)

I've modified your script as follows:

#!/usr/bin/sh
while :
do
echo HELLO
sleep 30 &
jobs -l
wait
echo WORLD
done
exit 0

When run, this will output the PID of the sleep command as:

[1] + 4960 Running

which you can then wake up using "kill -14" (or even "kill -9" come to that) and the script will cycle through the loop again.

Hope this is of help.

Cheers,

Ollie.
To err is human but to not award points is unforgivable
Ollie R
Respected Contributor

Re: traps, sleeping procs, shell scripting, oh my

Oops! Sorry! The transfer kept failing and... erm... well, this was the result! 8O)
To err is human but to not award points is unforgivable
Peter Kloetgen
Esteemed Contributor

Re: traps, sleeping procs, shell scripting, oh my

Hallo Jim,

First of all: What is your trap- command doing?

--> the only command inside is: echo some_thing

after executing this command, the script simply continues!

so change the trap- command to:

trap 'echo "signal catched"; exit 1'

This should work for you.

Allways stay on the bright side of life!

Peter
I'm learning here as well as helping
Wodisch
Honored Contributor

Re: traps, sleeping procs, shell scripting, oh my

Hi Jim,

the first explanation is about the signals 2 (=INTR) and 3 (=QUIT). Those are automagically set to "ignore" for every process run in the background (the shell does it), so your "trap" statement will never receive any signal 2 or 3.
Signals 1 and 15 should work fine, though.
The signals "USR1" and "USR2" are reserved for your own communication purposes, to not get into conflict with the existing and pre-defined signals, like "HUP" (=1) and INTR (=2) - see the output of "kill -l" for the complete list.

Then the "trap" statements are kind of *one-time-only*, so you would have to refresh/renew them (except for the "ignore" action).

HTH,
Wodisch
Vincent Fleming
Honored Contributor

Re: traps, sleeping procs, shell scripting, oh my

Jim,

You need a flag variable... see the following example. Note how I set CTRL when an INT is received. This works OK on my system.

Good luck!

#!/bin/sh
set -m
CTRL=1
trap 'echo CHLD' CHLD
trap 'echo EXIT' EXIT
trap 'echo HUP' HUP
trap 'echo INT' INT
trap 'echo QUIT' QUIT
trap 'echo TERM' TERM
trap 'echo DONE; CTRL=2; kill -ALRM $SLEEPPID' INT
echo $$ > $0.pid
echo CTRL is $CTRL
while [ $CTRL -eq 1 ]
do
echo CTRL is $CTRL
echo tick
sleep 5 &
SLEEPPID=$!
wait
echo $?
done
echo tock
echo CTRL is $CTRL
No matter where you go, there you are.
Jim Johnson_8
Occasional Contributor

Re: traps, sleeping procs, shell scripting, oh my

Jordan, Ollie, Vincent were right on with putting the sleep in the background and then adding the wait statement, which I had never used before. Now my traps occur immediately.

Peter, it doesn't really matter what I put in the trap statement, the fact was it didn't get trapped immediately. My point was to have a continously running process (daemon), and test sending different kill signals to it. To gracefully exit I would add a flag and maybe even a break (if stuck in some loop) as Vincent suggested. But this was just an example test script.

Woodisch, I'm still a little confused about your first paragraph. If you would have said that background processes ignore signal 1, then I might have understood, but with the sleep& and wait, signal 2 and 3 are trapped just fine by my process running in the background.

So, I'm still confused about signal 1 (SIGHUP). If I trap it, the process still dies (hangs up). Even if all my trap does is echo and I want the process to continue running.

Does anybody know how to properly trap a SIGHUP and keep the process running?

Thanks,
Jim