Название в значительной степени подводит итог. Есть ли разница между файлом оболочки и файлом php для cron Magento?
Если есть разница, есть ли причина для запуска одного вместо другого?
Название в значительной степени подводит итог. Есть ли разница между файлом оболочки и файлом php для cron Magento?
Если есть разница, есть ли причина для запуска одного вместо другого?
Ответы:
Файл cron.sh указывает на файл cron.php, поэтому вы должны указывать задачу cronjob на файл .sh.
По сути, внутри файла PHP находится вся логика для cron для получения заданий из Magento, а файл sh вызывает файл PHP.
cron.sh
Файл создан , чтобы проверить , что это не процесс хрон работает в Magento , прежде чем начать новый. Всегда используйте его как триггер. При определенных схемах безопасности с WHM / cPanel вам может быть запрещено запускать сценарии оболочки в качестве заданий cron, и только после этого вы можете напрямую запускаться cron.php
из crontab.
shell_exec
отключили в WHM / cPanel, но это не означает, что он сообщается как отключенный при cron.php
проверках ini_get('disable_functions')
. Таким образом, cron пытается запустить, видит shell_exec
как не отключенный, пытается использовать его и терпит неудачу, потому что он отключен.
Вы должны использовать cron.sh
, т.е.
* * * * * /bin/sh /var/www/html/magento/cron.sh
В зависимости от вашей среды, cron.sh
работает, cron.php
работает, cron.sh
работает cron.php
. Он разработан для того, чтобы cron Magento не выполнял задания несколько раз или порождал слишком много перекрывающихся процессов.
При первом запуске cron.sh
проверит текущие запущенные процессы, чтобы увидеть, cron.php
запущен ли уже (без каких-либо аргументов). Если нет, он выполнит
/usr/bin/php /var/www/html/magento/cron.php &
При cron.php
первом запуске (и в зависимости от того, поддерживает ли ваша ОС / хост) это будет происходить cron.sh
снова , дважды, но на этот раз с передачей аргументов:
/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 &
Вернувшись во cron.sh
второй раз, он снова проверит, работает ли cron с указанными параметрами. Если нет, он вернет его cron.php
либо с помощью либо, default
либо always
.
/usr/bin/php /var/www/html/magento/cron.php -mdefault &
/usr/bin/php /var/www/html/magento/cron.php -malways &
И в cron.php
последний раз, это заставит Magento запускать default
задания cron (почти все), а также always
задания cron (например enterprise_refresh_index
). Разделяя их на два процесса, он снижает риск длительной работы от блокировки других.
Используйте /bin/sh
для обработки этого скрипта
#!/bin/sh
Установите константу CRONSCRIPT
с файлом для вызова. $ 1 является первым аргументом, какcron.sh /whatever/path/cron.php
# location of the php binary
if [ ! "$1" = "" ] ; then
CRONSCRIPT=$1
else
CRONSCRIPT=cron.php
fi
установить другую константу, здесь вы можете передать always
или default
явно.
MODE=""
if [ ! "$2" = "" ] ; then
MODE=" $2"
fi
У cron нет переменных окружения, поэтому вы не можете просто вызвать php
. which
говорит вам, где живет бинарный файл php, скорее всего в/bin/php
PHP_BIN=`which php`
$0
это сам файл, как __FILE__
в php
# absolute path to magento installation
INSTALLDIR=`echo $0 | sed 's/cron\.sh//g'`
Не уверен, как именно это работает, но что он делает: звоните cron.php
с 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 нет рабочего каталога или какой-либо другой переменной окружения, поэтому рабочий каталог установлен.
// 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;
}
Если вы вызываете cron.php по curl или как-то, имена файлов являются фиксированными?
// 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);
Установите umask, который определяет, с какими разрешениями создаются новые файлы - нулевые разрешения, никому не разрешено ничего делать.
umask(0);
Убедитесь, что разрешены все функции, которые необходимы.
$disabledFuncs = explode(',', ini_get('disable_functions'));
$isShellDisabled = is_array($disabledFuncs) ? in_array('shell_exec', $disabledFuncs) : true;
$isShellDisabled = (stripos(PHP_OS, 'win') === false) ? $isShellDisabled : true;
устанавливать $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) {
если cronmode не установлен, мы вызываем cron.sh
оба режима
$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;
}
}
И тогда Мадженто наконец делает свою работу:
загрузить наблюдателей событий и добавить их в пул наблюдателей
Mage::getConfig()->init()->loadEventObservers('crontab');
Mage::app()->addEventArea('crontab');
Если shell_exec
отключено, отправляйте события, поэтому \Aoe_Scheduler_Model_Observer::dispatchAlways
и \Mage_Cron_Model_Observer::dispatch
выполняете задачи cron.
if ($isShellDisabled) {
Mage::dispatchEvent('always');
Mage::dispatchEvent('default');
} else {
Mage::dispatchEvent($cronMode);
}
} catch (Exception $e) {
Mage::printException($e);
exit(1);
}