Answers:
cron.sh指向cron.php文件,因此您应该将cronjob任务指向.sh文件。
基本上,PHP文件中包含cron从Magento检索作业的所有逻辑,而sh文件则调用PHP文件。
cron.sh
设置该文件是为了在启动新的Magento之前检查是否有cron进程正在运行。始终将其用作触发器。在使用WHM / cPanel的某些安全性方案下,可能不允许您将外壳程序脚本作为cron作业运行,只有这样才能直接cron.php
从crontab 运行。
shell_exec
在WHM / cPanel 中将其禁用,但这并不意味着在cron.php
check 时将其报告为已禁用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
。它旨在防止Magento的cron多次执行作业,或产生太多重叠的进程。
第一次运行时,cron.sh
将检查当前正在运行的进程,以查看是否cron.php
已经在运行(不带任何参数)。如果没有,它将执行
/usr/bin/php /var/www/html/magento/cron.php &
在cron.php
第一次运行时(并取决于您的OS /主机是否支持它),它将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;
}
如果通过curl或其他方式调用cron.php,文件名是否固定?
// 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;
}
}
然后,magento终于完成了自己的工作:
加载事件观察者并将其添加到观察者池
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);
}