29 Dec 2011 @ 8:42 PM 

Today, something a bit more complicated. This is a fun way to use a trap function we have seen yesterday .

The problem

You receive a new requirement from your customer (I did receive it a couple of times). You need to develop a program that will :

– Not consume CPU or disk until it is necessary.

– Read the content of a directory, then process each file in a directory A (move it to another directory B ) one by one. Not two files at the same time.

– Once the file has been “taken” by another process (no file in directory B), the next file can be published.

– You can’t have the system polling every minute or so, because the files need to be copied as fast as possible.

– The process that provides the files can start another process, but can’t wait more that a millisecond before giving the hand back.

Good luck…

The Solution

Well, at least the one I found, was to have a main process going to sleep, then being awoken by another one (triggered by the “file-provider”), and starts polling the directory A until it is empty. Then it goes back to sleep.

How ? well, like this :

First, we need to trap the “KILLUSR” signal :

trap “wakeup” 30

Then, we need to create a script, on the fly, that will be called to signal the main script that there is something to process (the “trigger” process)

trigger=trigger.sh
echo “#!/bin/ksh” >$trigger
echo “#Created by $0 on “`date` >>$trigger
echo ‘if [ “$1” == STOP ]’>>$trigger
echo “then” >>$trigger
echo “kill $$” >>$trigger
echo “else” >>$trigger
echo “kill -30 $$” >>$trigger
echo “fi” >>$trigger
echo “#End of the script” >>$trigger
chmod 755 $trigger

Next step, we create the function that will be executed in case of a trap.

_From=/from
_To=/to

wakeup () {
trap ‘echo “\c”‘ 30
# This is basically doing “noop”, to avoid being killed.
echo “Awoken at “`date` >>$0.log
while [ -f ${_From}/* ]
do
while [ -f ${_To}/* ]
do
sleep 1
done
File2Move=`ls -tr ${_From}| head -1`
mv ${_From}/${File2Move} ${_To}
done
echo “${_From} is empty” >>$0.log
}

And, last step, we need the code that will be executed while waiting :

while true
do
sleep 1800&
wait
done

When the script is waiting, the main part is just looping on sleep. Them, once it receives a trap, the function that does the copy is executed.

Afterwards, we take the first file sent, move it over, then wait until the destination directory is empty, and look for the next file.

If you have another idea on how this process could be done, feel free to comment !

Thank you for reading, and I hope to see you on tuesday !

Posted By: Dimi
Last Edit: 30 Dec 2011 @ 03:15 PM

EmailPermalinkComments (0)
Tags
Tags: , ,
Categories: Bash, Signals, Snippets
 28 Dec 2011 @ 8:00 PM 

Hello,

A very short one today, but it is usually not very well known.

As you know, Unix uses signals to communicate with processes. A process receives a signal, then takes an action. If no action is defined, the default action for most signals is to kill the process… which is maybe something you want to avoid.

The problem.

You have written the best script in the world, that does… let’s say… make ice-cream (we can dream).

The problem is that if someone kills your script (i.e. kill -15, SIGTEM, which is the default one), you process will simply stop, and throw ice-cream everywhere on the walls. (Ice-cream is here an image for temporary files).

How can you catch this message and close the ice-cream tap and clean-up a bit ?

The Solution.

Use trap.

At the beginning of your script, you can add the following line (after the shebang) :

trap 15 cleanup

This will trap the default SIGTERM, then start the procedure “cleanup” ( you need to define the “cleanup” procedure somewhere).

You can define a function that will do the cleanup for you, maybe add a message in the log, kill sub-processes, send mail, whatever is needed.

The only thing, is that you need to fail proof your function, in order to be sure that your process is not going in an infinite loop, because the way to kill it afterwards is to use another kill.

Note also that not all the signals might be trapped. Some of them, like the signal 9 (SIGKILL) is not trappable in a script.

Thank you for reading, and if I find some time, I’ll talk tomorrow about an inventive way to use the trap function.

Posted By: Dimi
Last Edit: 27 Dec 2011 @ 08:44 PM

EmailPermalinkComments (0)
Tags
Tags: , , ,
Categories: Bash, Signals, Snippets

 Last 50 Posts
Change Theme...
  • Users » 66
  • Posts/Pages » 25
  • Comments » 4
Change Theme...
  • VoidVoid « Default
  • LifeLife
  • EarthEarth
  • WindWind
  • WaterWater
  • FireFire
  • LightLight