Bash script overloads CPU on run
I've written two scripts one that starts the process if it hasn't been started already and the other that on start waits for the process to crash and then restarts it.
The one that causes problems is the latter. It's form is close to exact to it's sister script, bit a little slimmer because I just didn't want this one to do as much. On execution, this script causes the CPU to spike and hold at 100%. Since the two scripts are very alike, I don't know where the problem is. I've used the sleep, and echo "" > /dev/null, command to hold from sucking half my resources, but writing to /dev/null in a loop still sucks down the resources, and the script won't actually do anything if I use sleep. I've thought about using the wait command, but I'm unsure of how to use it here. Here's the script. Code:
#!/bin/bash |
You need to put a sleep statement in there so that it doesn't startup and simply loop infinitely as fast as the CPU will let it.
|
I think that, unless you're always bent on reinventing the wheel over and over again, searching LQ for similar threads and your distro repos, Freshmeat, Sourceforge, Nongnu, Berlios for similar apps should return usable ones (Monit?, Mon?) as this has been done times and times before. You could reduce it somewhat to something like
Code:
startApp() { [ -e /path/to/core ] && { doSomething; }; /path/to/application --args >/dev/null 2>&1 || startApp; }; startApp & |
@gnashley: Yes, I could, however as previously mentioned, adding the sleep statement DOES cut down the resources to an acceptable level, but doesn't allow the script to do anything.
@unSpawn: Yes, I COULD use Monit, and I'm familiar with it I could also use webmin, init.d, and numerous others, but I'm choosing to write my own because I want to get better at this sort of thing, and I find that I can prototype a project in shell script, then port it over to another language. In this case I want to use C eventually. I'm also not writing in-script functions because I want to keep things very flat for now. I have written prior versions of this script before, and I used crontab. Not knocking cron, but I want the script to always be monitoring the process in question. I picked apart your code and some stuff caught my fancy. Code:
if [[ ! -x /path/to/app ]] Code:
>/dev/null 2>&1 |
Quote:
|
[QUOTE=mashiox;3791332]I'm also not writing in-script functions because I want to keep things very flat for now.[/CODE]
OK. Then I suggest you drop the "-e" test from the code because "-x" basically implies "-e" and besides, if you expect to run your restart script (shipped with?) then you could also expect /path/to/app is installed (else why run it anyway?), right? Going one step further in the "mean and lean" dept., if you can expect your restart script to be run and /path/to/app to be previously installed then wouldn't it be fair to assert it's installed octal mode 0[5,7].* anyway? As in ditching the "-x" test as well? I mean basically the core functionality will only need to be one or another form of doing only two tests like 'pgrep /path/to/app || { [ -e core ] && doEmail; /path/to/app >/dev/null 2>&1; }', right? Quote:
|
Quote:
--- rod. |
Quote:
Concisely: The script I'm inquiring about initializes with this: Code:
if [ -n $tcore ] Code:
if [ -z "$tcore" ] Quote:
As far as the wall-of-code goes, I'm running with the Rule of Repair among others as articulated so well by Eric S. Raymond. |
I still say put a sleep in there -even a half-second will stop the over-racing of the CPU. It will not completely disable your script. Either that or write in *lots* of extra staements checking -e, -x, -s , -L and the kitchen sink so that the thing doesn't run so fast. Even though you don't sleep you are still not *continuously* checking because the routine does take some time to run -even though it may just be mili-seconds. EVen 'sleep .1' will stop it from racing.
|
Quote:
Try sleep 0.2 because its just going to keep racing without anything to slow it down. |
try to trap the SIGCHILD / SIGCHLD signal in bash. This automatically executes when a child process dies.
here we'll use read as a sleeper. Code:
shopt -s extglob Note, if you're adding more subprocesses, perhaps you can use an array and mark the PIDs of the subprocesses to tell which of them is still running or not. Code:
N=1234 |
All times are GMT -5. The time now is 10:19 PM. |