PHP shell_exec一会儿返回空字符串

问题描述 投票:0回答:2

我做了一个Symfony控制台命令,该命令使用pngquant处理和压缩一长串图像。从CSV文件读取图像。

该批次在本地环境中可以正常工作,直到结束,但是在舞台环境中,它可以工作约5分钟,然后开始从shell_exec命令返回空结果。我什至制作了一个重试系统,但是它总是返回空结果:

// escapeshellarg() makes this safe to use with any path
// errors are redirected to standard output
$command = sprintf(
    '%s --quality %d-%d --output %s --force %s 2>&1',
    $this->pngquantBinary,
    $minQuality,
    $maxQuality,
    escapeshellarg($tempPath),
    $path
);

// tries a few times
$data    = null;
$attempt = 0;

do {
    // command result
    $data = shell_exec($command);

    // error
    if (null !== $data) {
        $this->logger->warning('An error occurred while compressing the image with pngquant', [
            'command' => $command,
            'output'  => $data,
            'cpu'     => sys_getloadavg(),
            'attempt' => $attempt + 1,
            'sleep'   => self::SLEEP_BETWEEN_ATTEMPTS,
        ]);
        sleep(self::SLEEP_BETWEEN_ATTEMPTS);
    }

    ++$attempt;
} while ($attempt < self::MAX_NUMBER_OF_ATTEMPTS && null !== $data);

// verifies that the command has finished successfully
if (null !== $data) {
    throw new \Exception(sprintf('There was an error compressing the file with command "%s": %s.', $command, $data));
}

问题是在相同环境中在另一个shell中执行的相同命令可以正常工作!我的意思是,当我记录错误时,如果我将完全相同的命令放在同一服务器上的另一个实例中,则可以正常工作。

即使从Symfony日志中我也看不到任何错误,我应该在哪里查找更详细的错误?

是什么原因造成的?执行期间内存和处理器都很好!

php symfony shell-exec pngquant
2个回答
1
投票

如果使用(或不使用)Symfony Framework,建议使用Symfony Process组件代替shell_exec

在Symfony项目中,您可能会找到已安装的过程组件,但是,如果没有,则可以使用:下载该组件:

 composer require symfony/process

用法:

use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;

...


$process = new Process([
    $this->pngquantBinary,
    '--quality',
    sprintf('%d-%d', $minQuality, $maxQuality),
    '--output',
    $tempPath,
    '--force',
    $path
]);
$process->run();

// executes after the command finishes
if (!$process->isSuccessful()) {
    throw new ProcessFailedException($process);
}

$data = $process->getOutput();

请参见symfony documentation以获取更多示例。


0
投票

经过多次尝试,我读了这个问题:

Symfony2 Process component - unable to create pipe and launch a new process

解决方案是在循环期间刷新后向gc_collect_cycles添加一个调用!

if ($flush || 0 === ($index % self::BATCH_SIZE)) {
    $this->em->flush();
    $this->em->clear();

    // clears the temp directory after flushing
    foreach ($this->tempImages as $tempImage) {
        unlink($tempImage);
    }
    $this->tempImages = [];

    // forces collection of any existing garbage cycles
    gc_collect_cycles();
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.