12

I'm calling this in my php script:

    exec("gutschein.php >/dev/null 2>&1 &");

Calling the script (generates a pdf and sends it away by e-mail) works, but the process is not running in the background (I checked it out with a sleep statement inside gutschein.php). The browser is hanging until execution of gutschein.php is finished.

I also checked out the following:

    exec("/usr/bin/php gutschein.php >/dev/null 2>&1 &");

or

shell_exec("/usr/bin/php gutschein.php >/dev/null 2>&1 &");

It doesn't change anything. The script is actually running on a linux server. Has anybody an idea what I'm doing wrong?

Ilmari Karonen
  • 49,047
  • 9
  • 93
  • 153
cesare
  • 175
  • 1
  • 2
  • 8
  • If I remember correctly, when you run a command with a `&` from a shell you still need to press a key to get the prompt back. Wouldn't it be the same for PHP? – Tchoupi Sep 18 '12 at 12:20
  • 2
    @MathieuImbert: You remember incorrectly. – Wooble Sep 18 '12 at 12:22
  • better aproach to this problem would be to create a query with commands (tasks) to run, and another process (in.e. run from CRON) could consume the quey and execute commands ony by one... – Greg Motyl Sep 18 '12 at 12:23
  • check with pass_through also.. – arun Sep 18 '12 at 12:23
  • try to `fork` first, then `exec` ? – wroniasty Sep 18 '12 at 12:27
  • you can not fork from apache, it is only possible if you ran script directly from php – Greg Motyl Sep 18 '12 at 12:29
  • @grzegorz_motyl: if i can't manage to make exec() run properly i will go for this option (is more complicated) – cesare Sep 18 '12 at 12:46
  • Have you tried without redirecting the output? simply exec("/usr/bin/php gutschein.php"). You could get the output into an array (passed by reference as the second parameter to exec) and discard it if you don't need it – ibtarek Sep 18 '12 at 14:33
  • @ibtarek: yes. it wouldn't run in the background either... – cesare Sep 18 '12 at 14:50

7 Answers7

4

Try system and/or passthru. I've had issues with exec before because it halts trying to fill the return array with data until the process has finished.

These will both echo raw output so even if they work you may need to handle that with a discarded output buffer.

MattLBeck
  • 5,701
  • 7
  • 40
  • 56
Dave
  • 219
  • 1
  • 7
2
    /**
     * @author Micheal Mouner
     * @param String $commandJob
     * @return Integer $pid
     */
    public function PsExec($commandJob)
    {
        $command = $commandJob . ' > /dev/null 2>&1 & echo $!';
        exec($command, $op);
        $pid = (int) $op[0];
        if ($pid != "")
            return $pid;
        return false;
    }

This worked for me .. check it

also, return processId of the background process

1

Can you try one of the following 2 commands to run background jobs from PHP:

$out = shell_exec('nohup /usr/bin/php /path/to/gutschein.php >/dev/null 2>&1 &');

OR

$pid = pclose(popen('/usr/bin/php gutschein.php', 'r'));

It will execute the command in background and returns you the PID, which you can check using condition $pid > 0 to ensure it has worked.

anubhava
  • 761,203
  • 64
  • 569
  • 643
  • the script is executed. that is not the problem. the problem is that its not executed in the background... – cesare Sep 18 '12 at 13:05
  • I have tried above commands via a browser and it was indeed executed in background. – anubhava Sep 18 '12 at 13:09
  • i checked out your 2 suggestions. they execute the script like a charm but unfortunately not in the background...in my case it doesn't work. – cesare Sep 18 '12 at 13:16
  • I find it strange since I am able to run above script in background in my browser (not on command line). I suspect there is some php.ini setting on your host that is preventing PHP executing a background job. – anubhava Sep 18 '12 at 13:24
  • maybe. but they should know actually... could the problem have something to do with "Output Buffering? – cesare Sep 18 '12 at 13:35
1

All output must be redirected, else the script will hang as long as gutschein.php executes. Try

exec('/usr/bin/php gutschein.php &> /dev/null &');
Martin Müller
  • 2,565
  • 21
  • 32
  • i'm already redirecting: ">/dev/null 2>&1". I checked out your suggestion, but it doesn't work – cesare Sep 18 '12 at 12:49
1

You can use screen: screen -d -m /usr/bin/php gutschein.php

Here is screen's manual if you need more info on options.

lupatus
  • 4,208
  • 17
  • 19
1

Please see my experience at HERE. The way I try and works for me -

php -q /path/to/my/test/script/cli_test.php argument1 < /dev/null &

In PHP, it is like

exec('php -q /path/to/my/test/script/cli_test.php argument1 < /dev/null &')
chf
  • 51
  • 4
-3

The browser is might waiting for a response, so let your script produce any output and terminate the "main process". a simple

die('ok');

should do the job.


btw, forking a new process by calling exec is might not the best solution since the new process isn't a real child process - means you can't control it. you might consider using pcntl (http://php.net/manual/de/book.pcntl.php) for this purpose. but stand clear, this extension has also his pitfalls, especially in the context of a webserver.

passioncoder
  • 909
  • 6
  • 10