Hi Will,
Normally, when someone asks a question involving BASH, I'm expecting that BASH is what they prefer to use, to do whatever it is that they are doing.
I'm expecting that if they know for example, PERL, and they wanted to use PERL, they would have asked the question in terms of PERL. So if they ask about something in terms of BASH, and I have anything to contribute on the subject, I'll try to give them something in terms of BASH.
I could be missing something here, but
very roughly, I suspect it might be about fair to say that if I listed a few languages that can monitor/control processes, and ordered the list from least direct/simple/complete control available in the language, to most direct/simple/complete control, the list would be BASH, GAWK, PERL, C. In a Unix or Unix-like environment, C tends to have most of the process monitoring/controlling capabilities that the Kernel does. As a result, of those languages, it would be my first choice for any detailed process monitoring/controlling.
So I wasn't asking you to demonstrate knowledge. Instead I was wondering with what features of BASH, you might be comfortable, or, if you are in a position to accomplish your goal using some language other than BASH script.
If you are just talking about executing programs, and limiting the number of programs executing, you could do something simple in BASH, such as:
Code:
job_list=( './prog_a.bash' './prog_b.bash' './prog_c.bash' './prog_d.bash' './prog_e.bash' './prog_f.bash' './prog_g.bash' './prog_h.bash' ) ;
next_job=0 ;
jobs_in_list=8
job_count_limit=3 ;
job_count=`jobs -p | wc -l` ;
while :
do
job_count=`jobs -p | wc -l` ;
echo "`date +'%Y/%m/%d@%H:%M:%S'` Count of jobs running: $job_count"
while [[ $job_count -lt $job_count_limit ]]
do
echo "`date +'%Y/%m/%d@%H:%M:%S'` Running ${job_list[ $next_job ]}"
( ${job_list[ $next_job ]} ) &
next_job=$(( $next_job + 1 ))
next_job=$(( $next_job % $jobs_in_list ))
sleep 3
job_count=`jobs -p | wc -l` ;
echo "`date +'%Y/%m/%d@%H:%M:%S'` Count of jobs running: $job_count"
done
sleep 60
done
Naturally the "round robin" job list is an over simplification, unless you're trying to write something like cron.
It now sounds almost as if you're trying to write something like an
at Daemon.
If you wanted almost anything beyond simply limiting the number of programs running, you might get into trouble, or at least deep Kludge, pretty quickly with BASH.
For example, if you wanted the programs run by the BASH script to be killed off, when the BASH script is killed off, you might add one or more
traps to the BASH script.
Something like this code:
Code:
running_job_sets=`jobs | awk -F'[\\\]\\\[]' ' { printf "%%%s " , $2 ; } END { print "" ; } '` ;
kill $running_job_sets ;
can work from an "interactive" BASH shell; it can kill off not only something run from the BASH script, but also other programs that those programs run.
But run it from a BASH script running in the "background", and you'll tend to
only kill the programs run directly by the BASH script.
If you run BASH in the background, you can pass the argument to BASH itself to tell it that you want to run BASH interactively, and even try to connect BASH to pseudo-tty's to make BASH "think" it's interactive.
You can try to make use of other Inter-Process Communication facilities in Linux, for use with your BASH script.
Yet in a sense with those approaches, you're more or less trying to add-on, or make facilities available to your BASH environment, that are already directly available in C.
If you are worried about the System being run out of resources, you might want to look into placing resource limits on the jobs that you will be running. Unless, your goal is ultimately to monitor resource usage, and react accordingly, rather then impose limits; there are facilities in C for monitoring resource usage of child processes.
Although I have repeatedly been impressed with how quickly some language processors have been able to run programs written in "scripting languages", a similarly written compiled program running "native code" is still hard to beat.
Imagine a so called "Rabbit Job" that starts quickly spawning one process after another process. If by the time you've gotten a particular PID and tried to kill off one process, it's gone, and there's a different process with a different PID in its place, naturally the program trying to control that situation needs to be pretty speedy.
That's another thing to recommend C if you are dealing with monitoring of processes that might not be "well behaved". Naturally process states can change rather quickly, so you don't want your program to be chasing it's own tail, if it doesn't react sufficiently fast, it can effectively create its own "race conditions".
If I still don't have a good idea of what you're trying to accomplish, maybe you could give us some additional details, to help us, help you better.
HTH.