Différence entre les fichiers Shell et PHP Cron dans 1.9

16

Le titre résume assez bien. Y a-t-il une différence entre le fichier shell et le fichier php pour le cron Magento?

S'il y a une différence, y a-t-il une raison pour exécuter l'un au lieu de l'autre?

Chris Morris
la source
Vous feriez mieux d'utiliser cron.sh, il vérifiera si un processus cron.php est en cours d'exécution avant de l'appeler.
Tai Christian

Réponses:

7

Le cron.sh pointe vers le fichier cron.php, vous devez donc pointer votre tâche cronjob vers le fichier .sh.

Fondamentalement, à l'intérieur du fichier PHP se trouve toute la logique pour que le cron récupère les travaux de Magento et le fichier sh appelle le fichier PHP.

mbalparda
la source
4
Le cron.shfichier est configuré pour vérifier qu'aucun processus cron ne s'exécute dans Magento avant d'en démarrer un nouveau. Utilisez-le toujours comme déclencheur. Dans certains schémas de sécurité avec WHM / cPanel, il se peut que vous ne soyez pas autorisé à exécuter des scripts shell en tant que tâches cron et que vous exécutez ensuite directement à cron.phppartir de crontab.
Fiasco Labs
Pour ajouter à @FiascoLabs, vous pouvez avoir shell_execdésactivé dans WHM / cPanel, mais cela ne signifie pas qu'il est signalé comme désactivé lors des cron.phpvérifications ini_get('disable_functions'). Donc cron essaie de s'exécuter, voit shell_execcomme non désactivé, essaie de l'utiliser et échoue car il est désactivé. haussement d'épaules
pspahn
7

Vous devriez utiliser cron.sh, c.-à-d.

* * * * * /bin/sh /var/www/html/magento/cron.sh

En fonction de votre environnement, cron.shexécute cron.phpqui s'exécute, cron.shqui s'exécute cron.php. Il est conçu pour empêcher le cron de Magento d'exécuter des tâches plusieurs fois ou de générer trop de processus qui se chevauchent.


La première fois qu'il est exécuté, cron.shvérifiera les processus en cours d'exécution pour voir s'il cron.phpest déjà en cours d'exécution (sans aucun argument). Sinon, il s'exécutera

/usr/bin/php /var/www/html/magento/cron.php &

Le cron.phppremier run (et selon que votre système d' exploitation / supports de l' héberger) il va produire à cron.sh nouveau , deux fois, mais cette fois -ci passer des arguments:

/bin/sh /var/www/html/magento/cron.sh cron.php -mdefault 1 > /dev/null 2>&1 &
/bin/sh /var/www/html/magento/cron.sh cron.php -malways 1 > /dev/null 2>&1 &

De retour cron.shpour la deuxième fois, il vérifiera à nouveau si cron fonctionne avec les paramètres spécifiés. Sinon, il le renverra cron.phpavec defaultou always.

/usr/bin/php /var/www/html/magento/cron.php -mdefault &
/usr/bin/php /var/www/html/magento/cron.php -malways &

Et cron.phppour la dernière fois, cela déclenchera Magento pour exécuter defaultdes tâches cron (à peu près toutes), ainsi que alwaysdes tâches cron (comme enterprise_refresh_index). En les séparant en deux processus, cela réduit le risque qu'un travail de longue durée ne bloque les autres.

Steve Robbins
la source
4

cron.sh

Utiliser /bin/shpour traiter ce script

#!/bin/sh

Définissez une constante CRONSCRIPTavec le fichier à appeler. $ 1 est le premier argument, commecron.sh /whatever/path/cron.php

# location of the php binary
if [ ! "$1" = "" ] ; then
    CRONSCRIPT=$1
else
    CRONSCRIPT=cron.php
fi

définir une autre constante, ici vous pouvez passer alwaysou defaultexplicitement.

MODE=""
if [ ! "$2" = "" ] ; then
    MODE=" $2"
fi

cron n'a pas de variables d'environnement, donc vous ne pouvez pas simplement appeler php. whichvous dit, où le binaire php est vivant, très probablement dans/bin/php

PHP_BIN=`which php`

$0est le fichier lui-même, comme __FILE__dans php

# absolute path to magento installation
INSTALLDIR=`echo $0 | sed 's/cron\.sh//g'`

Je ne sais pas exactement comment cela fonctionne, mais ce qu'il fait: appeler cron.phpavec php.

#   prepend the intallation path if not given an absolute path
if [ "$INSTALLDIR" != "" -a "`expr index $CRONSCRIPT /`" != "1" ];then
    if ! ps auxwww | grep "$INSTALLDIR$CRONSCRIPT$MODE" | grep -v grep 1>/dev/null 2>/dev/null ; then
        $PHP_BIN $INSTALLDIR$CRONSCRIPT$MODE &
    fi
else
    if  ! ps auxwww | grep "$CRONSCRIPT$MODE" | grep -v grep | grep -v cron.sh 1>/dev/null 2>/dev/null ; then
        $PHP_BIN $CRONSCRIPT$MODE &
    fi
fi

cron.php

Comme déjà dit, cron n'a pas de répertoire de travail ni aucune autre variable d'environnement, donc le répertoire de travail est défini.

// Change current directory to the directory of current script
chdir(dirname(__FILE__));

require 'app/Mage.php';

if (!Mage::isInstalled()) {
    echo "Application is not installed yet, please complete install wizard first.";
    exit;
}

Si vous appelez cron.php par curl ou quelque chose, les noms de fichiers sont fixes?

// Only for urls
// Don't remove this
$_SERVER['SCRIPT_NAME'] = str_replace(basename(__FILE__), 'index.php', $_SERVER['SCRIPT_NAME']);
$_SERVER['SCRIPT_FILENAME'] = str_replace(basename(__FILE__), 'index.php', $_SERVER['SCRIPT_FILENAME']);

Mage::app('admin')->setUseSessionInUrl(false);

Définissez umask, qui définit avec quelles autorisations les nouveaux fichiers sont créés - zéro autorisation, personne n'est autorisé à faire quoi que ce soit.

umask(0);

Assurez-vous que toutes les fonctions sont autorisées et nécessaires.

$disabledFuncs = explode(',', ini_get('disable_functions'));
$isShellDisabled = is_array($disabledFuncs) ? in_array('shell_exec', $disabledFuncs) : true;
$isShellDisabled = (stripos(PHP_OS, 'win') === false) ? $isShellDisabled : true;

ensemble $cronmode

try {
    if (stripos(PHP_OS, 'win') === false) {
        $options = getopt('m::');
        if (isset($options['m'])) {
            if ($options['m'] == 'always') {
                $cronMode = 'always';
            } elseif ($options['m'] == 'default') {
                $cronMode = 'default';
            } else {
                Mage::throwException('Unrecognized cron mode was defined');
            }
        } else if (!$isShellDisabled) {

si cronmode n'est pas défini, nous appelons cron.shavec les deux modes

            $fileName = basename(__FILE__);
            $baseDir = dirname(__FILE__);
            shell_exec("/bin/sh $baseDir/cron.sh $fileName -mdefault 1 > /dev/null 2>&1 &");
            shell_exec("/bin/sh $baseDir/cron.sh $fileName -malways 1 > /dev/null 2>&1 &");
            exit;
        }
    }

Et puis magento fait enfin son travail:

  • charger des observateurs d'événements et les ajouter au pool d'observateurs

    Mage::getConfig()->init()->loadEventObservers('crontab');
    Mage::app()->addEventArea('crontab');

si shell_execest désactivé, répartissez les événements \Aoe_Scheduler_Model_Observer::dispatchAlwayset \Mage_Cron_Model_Observer::dispatchexécutez les tâches cron.

    if ($isShellDisabled) {
        Mage::dispatchEvent('always');
        Mage::dispatchEvent('default');
    } else {
        Mage::dispatchEvent($cronMode);
    }
} catch (Exception $e) {
    Mage::printException($e);
    exit(1);
}
Fabian Blechschmidt
la source