今天遇见一个十分坑逼的问题,那就是我写了一个PHP脚本,生成.sh脚本,然后执行,判断次sh脚本是否执行成功。在linux下面执行php脚本,一切正常,但是由于我们需要定时跑脚本,所以加入了crontab的定时脚本任务,但是经过测试,每次脚本都不会执行成功。匪夷所思的问题,网上查了一下也没发现什么原因。具体代码如下:
private function syncS3File($filePath, $count = 0)
{
$pgCache = new \pgc\caching\PGCache('cache.bmall');
$cacheKey = 'unity_big_data_process_' . date('Ymd');
//生成shell脚本
$s3Shell = $filePath . 's3.sh';
$s3Config = \Yii::$app->params['s3Config'];
$awsS3Region = $s3Config['region'];
$awsS3KeyId = $s3Config['accessKeyId'];
$awsS3AccessKey = $s3Config['secretAccessKey'];
$awsS3Url = self::UNITY_BIG_DATA_URL;
$awsS3FilePath = $filePath . 'gz'; //s3 gz目录
if (!file_exists($s3Shell)) {
$content = '#!/usr/bin/env bash
export AWS_DEFAULT_REGION=' . $awsS3Region . '
export AWS_ACCESS_KEY_ID=' . $awsS3KeyId . '
export AWS_SECRET_ACCESS_KEY=' . $awsS3AccessKey . '
aws s3 sync ' . $awsS3Url . ' ' . $awsS3FilePath . '
';
file_put_contents($s3Shell, $content, LOCK_EX);
chmod($s3Shell, 0755);
}
//调用shell脚本,同步s3数据
system($s3Shell, $result);
//result为0代表同步成功,为1代表同步失败
if ($result == 0) {
//获取
return $awsS3FilePath;
} else {
$count = $count + 1;
if ($count > 20) {
$pgCache->set($cacheKey, self::UNITY_BIG_DATA_FAILED, self::UNITY_BIG_DATA_CACHE_TIME);
throw new ErrorException('获取s3的unity数据失败', 500);
}
$this->syncS3File($filePath, $count);
}
return $awsS3FilePath;
}
经过测试发现system的结果错误代码是127,最后单独把这个代码放入测试脚本,把所有输出都显示出来。
/home/worker/s3.sh >> 1.log 2&1
结果发现aws 命令不存在,原来是因为crontab -e 里面的路径是/sbin:/bin:/usr/sbin:/usr/bin,而我们安装的aws是在/home/worker/python/bin,所以我在Linux下面执行的时候,是worker账号执行的,是能查询到/home/worker/python/bin的. 于是答案就知晓了,只需要在crontab -e的最底部加上:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/home/worker/bin:/home/worker/python/bin
这下crontab可以正常执行脚本了。
Be the First to comment.