0

I have this shell script from ISPConfig:

#!/bin/sh PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin . /etc/profile umask 022 if [ -f /usr/local/ispconfig/server/lib/php.ini ]; then PHPINIOWNER=`stat -c %U /usr/local/ispconfig/server/lib/php.ini` if [ $PHPINIOWNER == 'root' ] || [ $PHPINIOWNER == 'ispconfig' ]; then export PHPRC=/usr/local/ispconfig/server/lib fi fi cd /usr/local/ispconfig/server /usr/bin/php -q /usr/local/ispconfig/server/server.php cd /usr/local/ispconfig/security /usr/bin/php -q /usr/local/ispconfig/security/check.php 

This script is executed by cron each minute, but I need to make it recursive, that is, finish script and repeat itself.

I tried adding this on the last line:

sh /usr/local/ispconfig/server/server.sh 

but for some reason, consumes all memory in a few minutes.

how can I solve it?

2 Answers 2

2

When you recurse by invoking it at the end like that you are never letting the parent's finish and will use all your process allotment and/or memory. You could use exec to replace your current process with a new instance of it though:

exec sh /usr/local/ispconfig/server/server.sh 

That way your current process will just be replaced by a fresh copy, instead of having an ever growing chain of children.

2

I guess what you really want is to repeat the script in an endless loop.

So, instead of doing this recursively (really bad idea, as you found out) or with exec, I propose to just loop it:

!/bin/sh PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin . /etc/profile umask 022 if [ -f /usr/local/ispconfig/server/lib/php.ini ]; then PHPINIOWNER=`stat -c %U /usr/local/ispconfig/server/lib/php.ini` if [ $PHPINIOWNER == 'root' ] || [ $PHPINIOWNER == 'ispconfig' ]; then export PHPRC=/usr/local/ispconfig/server/lib fi fi while : do cd /usr/local/ispconfig/server /usr/bin/php -q /usr/local/ispconfig/server/server.php cd /usr/local/ispconfig/security /usr/bin/php -q /usr/local/ispconfig/security/check.php done 

This way, you repeat everything between do and done immediately and endlessly.

That said, you have to be careful as even this can have a big impact on your system, as you are forking new PHP interpreters all the time. Does this stuff really need to run more than once a minute? What does it do anyway?

2
  • I like your suggestion. No need to reprocess part of the code. To answer your question, this script (php) processes email accounts, and the closer to real time, better for the end user who will have your changes immediately processed. A doubt, from the moment that this script is run, in which situations it may have to stop running? Basically, I need it to remain always running (failsafe). Commented Jun 18, 2016 at 16:23
  • The part between do and done will never terminate, as the while : doesn't have any termination condition. This script could only be killed by kill (or a CTRL-C when running in the console), and this is pretty bad style - consider it as just a demonstration of the concept. I don't think it would be good performance wise to really have this process possibly multiple times per second - add sleep 5 before the done to let it wait a few seconds before the next run. Commented Jun 18, 2016 at 16:43

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.