如何用ctrl+c和kill命令正确终止正在运行的命令或进程

96 阅读1分钟

在下面的例子中,我们将使用pcntl_signal 函数,让我们的命令先完成它的工作,然后退出。它对于防止源于ctrl+c 动作和kill PID 命令的意外终止很有用。我们将使用一个symfony命令作为例子。

命令

我只是打印一条信息,但你可以用它来关闭数据库连接、保存数据、关闭文件、写到日志文件等。

namespace AppBundle\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class HelloCommand extends Command
{
    /** @var OutputInterface */
    private $output;

    protected function configure()
    {
        $this->setName('hello');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->output = $output;

        declare(ticks = 1);

        pcntl_signal(SIGINT, [$this, 'doInterrupt']);
        pcntl_signal(SIGTERM, [$this, 'doTerminate']);

        while (true) {
            $output->writeln('Hello '.date('s'));

            sleep(1);
        }
    }

    /**
     * Ctrl-C
     */
    private function doInterrupt()
    {
        $this->output->writeln('Interruption signal received.');

        exit;
    }

    /**
     * kill PID
     */
    private function doTerminate()
    {
        $this->output->writeln('Termination signal received.');

        exit;
    }
}

kill PID test

$ bin/console hello
Hello 36
Hello 37
Hello 38
Hello 39
Termination signal received.

CTRL+C test

$ bin/console hello
Hello 17
Hello 18
Hello 19
^C
Interruption signal received.