Назад | Перейти на главную страницу

Как сделать рекурсивный сценарий оболочки?

У меня есть сценарий оболочки от 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

Этот сценарий выполняется cron каждую минуту, но мне нужно сделать его рекурсивным, то есть завершить сценарий и повторить его.

Я попытался добавить это в последнюю строку:

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

но почему-то занимает всю память за несколько минут.

как я могу это решить?

Я полагаю, что вам действительно нужно повторять сценарий в бесконечном цикле.

Итак, вместо того, чтобы делать это рекурсивно (действительно плохая идея, как вы выяснили) или с exec, Предлагаю просто зациклить:

!/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

Таким образом, вы повторяете все между do и done сразу и бесконечно.

Тем не менее, вы должны быть осторожны, поскольку даже это может иметь большое влияние на вашу систему, поскольку вы все время создаете новые интерпретаторы PHP. Делает это действительно нужно запускать чаще, чем раз в минуту? Что он вообще делает?

Когда вы выполняете рекурсию, вызывая его в конце таким образом, вы никогда не позволяете родительскому завершению и будете использовать все выделенные вам процессы и / или память. Вы могли бы использовать exec чтобы заменить текущий процесс новым его экземпляром:

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

Таким образом, ваш текущий процесс будет просто заменен новой копией, вместо того, чтобы иметь постоянно растущую цепочку потомков.