Laravel5:如果没有准备好运行的命令,如何禁用默认调度程序消息

时间:2019-02-14 09:42:57

标签: php laravel-5 scheduler

使用Laravel5 scheduler时:

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

如果没有准备好运行的命令,我们将收到以下默认输出:

# No scheduled commands are ready to run.

如何禁用此默认Laravel5消息?如果没有准备好运行的命令,我们不希望有输出。最好的情况是,当我们能够配置该消息并自行返回代码时。

4 个答案:

答案 0 :(得分:3)

您可以在app/Console/Commands中创建一个类似于以下内容的新命令,以扩展默认的schedule:run命令。

它会覆盖handle方法,同时将其他所有内容保持原样,以避免Laravel输出“未准备好运行任何计划的命令”。什么也没做的时候排成一行。

通过使用其他名称,无需担心冲突,如果需要,您仍然可以随时运行原始的php artisan schedule:run命令。

<?php

namespace App\Console\Commands

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Console\Scheduling\ScheduleRunCommand;

class RunTasks extends ScheduleRunCommand
{
    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'run:tasks';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Custom task runner with no default output';

    /**
     * Create a new command instance.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    public function __construct(Schedule $schedule)
    {
        parent::__construct($schedule);
    }

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function handle()
    {
        foreach ($this->schedule->dueEvents($this->laravel) as $event) {
            if (! $event->filtersPass($this->laravel)) {
                continue;
            }
            if ($event->onOneServer) {
                $this->runSingleServerEvent($event);
            } else {
                $this->runEvent($event);
            }
            $this->eventsRan = true;
        }

        if (! $this->eventsRan) {
            // Laravel would output the default text here. You can remove
            // this if statement entirely if you don't want output.
            //
            // Alternatively, define some custom output with:
            // $this->info("My custom 'nothing ran' message");
        }
    }
}

验证Laravel看到了您的新命令:

php artisan | grep run:tasks

最后更新您的cron以运行新命令:

* * * * * cd /path-to-your-project && php artisan run:tasks >> /dev/null 2>&1

答案 1 :(得分:1)

正如我在评论中提到的,我看到两种可能性

您可以filter the output,通过删除不需要的内容

* * * * * cd /path-to-your-project && php artisan schedule:run | awk '{ if (/No scheduled commands are ready to run./ && !seen) { seen = 1 } else print }'

或者您可以使用自己的命令覆盖:

$ php artisan make:command ScheduleRunCommand

通过创建自己的命令(主要是从ScheduleRunCommand复制/粘贴)或按照{dave-s的建议扩展ScheduleRunCommand

如果您仍要使用新命令运行php artisan schedule:run, 您需要在服务提供商中注册

$this->app->extend('schedule.run', function () {
    return new \App\Console\Commands\ScheduleRunCommand;
});

答案 2 :(得分:1)

如果您在https://github.com/laravel/framework/blob/78505345f2a34b865a980cefbd103d8eb839eedf/src/Illuminate/Console/Scheduling/ScheduleRunCommand.php#L82上查看Laravel的代码,

public function handle()
{
    foreach ($this->schedule->dueEvents($this->laravel) as $event) {
        if (! $event->filtersPass($this->laravel)) {
            continue;
        }
        if ($event->onOneServer) {
            $this->runSingleServerEvent($event);
        } else {
            $this->runEvent($event);
        }
        $this->eventsRan = true;
    }
    if (! $this->eventsRan) {
        $this->info('No scheduled commands are ready to run.');
    }
}

您看到它是通过$ this-> info处理程序处理的。

信息处理程序在Command.php中定义,该方法调用line方法,在output handler中定义的run command

因此,从本质上讲,要能够拦截此错误,您应该能够在运行所调用文件中的命令之前绑定自己的输出处理程序,从而覆盖基于OutputStylesymfonystyle您的Cron工作。

我能想到的最佳工作方案是使用OutputFormatter,当字符串与目标字符串匹配时,您只需返回null。

 $this->output->setFormatter( new MyCatchemAllFormatter() );

在该类中,您将根据以下内容定义一些内容:

use Symfony\Component\Console\Formatter\OutputFormatter;

class MyCatchemAllFormatter extends OutputFormatter 
{
    public function formatAndWrap(string $message, int $width) 
    {
        if($message != 'No scheduled commands are ready to run.') {
             return parent::formatAndWrap($message, $width);
        }
        return null;
    }
}

答案 3 :(得分:0)

  

我知道我的解决方案是 DIRTY ,大​​多数SO用户都会对此表示反对,但是无需注册其他服务提供商,修改类等即可快速完成。

我检查了源,并在ScheduleRunCommand 81 行中找到了this,即

public function handle()
{
    foreach ($this->schedule->dueEvents($this->laravel) as $event) {
        if (! $event->filtersPass($this->laravel)) {
            continue;
        }
        if ($event->onOneServer) {
            $this->runSingleServerEvent($event);
        } else {
            $this->runEvent($event);
        }
        $this->eventsRan = true;
    }
    if (! $this->eventsRan) { // L81
        $this->info('No scheduled commands are ready to run.'); // L82
    }
}

“作弊”的最快方法是将类复制到app/Console/ScheduleRunCommand.php,并在每次调用composer dump-autoload时将该文件复制到原始源路径。

1)将原始文件复制到app/Console文件夹:

cp vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleRunCommand.php patch/ScheduleRunCommand.php app/Console/ScheduleRunCommand.php

2)在composer.json scripts:post-autoload-dump 部分中添加这样的行:

cp app/Console/ScheduleRunCommand.php vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleRunCommand.php

3)修改您在app/Console/ScheduleRunCommand.phpL82)中的消息:

if (! $this->eventsRan) {
    $this->info('NOTHING');
}

4)运行:composer dump

和结果:

class patching