24

I'm trying to process a file in the background with the following command, but it does nothing.

exec("php csv.php $file $user > /dev/null &", $output);

If I remove > /dev/null & then the file processes, but not in the background.

exec("php csv.php $file $user", $output);

Any ideas?

kylex
  • 14,178
  • 33
  • 114
  • 175
  • Did you try using passthru or popen? I have never used exec, but I'm sure it works with both of them. – Ben Jan 28 '13 at 05:33
  • You shouldn't be expecting an output if you want it to run async. Also i would precede the exec with an "@" – Emery King Jan 28 '13 at 05:35

3 Answers3

48

Note:

If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.

http://php.net/manual/en/function.exec.php

so:

exec("php csv.php $file $user > /dev/null &"); // no $output
Emery King
  • 3,550
  • 23
  • 34
1

Have you considered using screen? You can start up a screen session that runs in a detached process. Output will go to the screen session, which you can reattach to in another terminal while it is still running.

exec("screen -d -m -S my_php_session csv.php $file $user", $output);
moodboom
  • 6,225
  • 2
  • 41
  • 45
0

In addition to Emery King's answer, you must use a single exec() call in order to kill a background process. At first, I was under the impression that if the process was put in the background, I could go on my merry way and kill it later as long as I had the process ID, but that is not the case.

For example:

// Runs the background process for 10 seconds
// and then kills it and allows php to continue
exec('sh -c \'echo $$ > pid; exec long_running_process\' > /dev/null 2>&1 & sleep 10 && kill $(cat pid)');

// Runs the background process but does not allow
// php to continue until the background process finishes.
exec('sh -c \'echo $$ > pid; exec long_running_process\' > /dev/null 2>&1 &');
exec(' sleep 10 && kill $(cat pid)'); // <- does not execute until background process is done (at which point pid is already dead)
  • echo $$ > pid writes the process ID of the long_running_process into a file named pid.

  • > /dev/null 2>&1 & redirects stdout and stderr to /dev/null and puts long_running_process into the background.

  • sleep 10 && kill $(cat pid) waits 10 seconds before killing the process who's ID is in the pid file.

Stack Underflow
  • 2,363
  • 2
  • 26
  • 51