Take the 2-minute tour ×

I've got a PHP script that needs to invoke a shell script but doesn't care at all about the output. The shell script makes a number of SOAP calls and is slow to complete, so I don't want to slow down the PHP request while it waits for a reply. In fact, the PHP request should be able to exit without terminating the shell process.

I've looked into the various exec(), shell_exec(), pcntl_fork(), etc. functions, but none of them seem to offer exactly what I want. (Or, if they do, it's not clear to me how.) Any suggestions?

share|improve this question

11 Answers 11

up vote 110 down vote accepted

If it "doesn't care about the output", couldn't the exec to the script be called with the & to background the process?

EDIT - incorporating what @AdamTheHut commented to this post, you can add this to a call to exec:


That will redirect both stdio (first >) and stderr (2>) to /dev/null and run in the background.

There are other ways to do the same thing, but this is the simplest to read.

An alternative to the above double-redirect:

" &> /dev/null &"
share|improve this answer
This seems to work, but it needs a little more than an ampersand. I got it working by appending "> /dev/null 2>/dev/null &" to the exec() call. Although I have to admit I'm not exactly sure what that does. –  AdamTheHutt Oct 21 '08 at 19:04
that redirects stdio to /dev/null and stderr to /dev/null .. good catch on the addition to the call –  warren Oct 22 '08 at 14:48
Definitely the way to go if you want fire and forget with php and apache. A lot of production Apache and PHP environments will have pcntl_fork() disabled. –  method Aug 19 '09 at 21:10
Just a note for &> /dev/null &, xdebug won't generate logs if you use this. Check stackoverflow.com/questions/4883171/… –  kapeels Feb 4 '11 at 4:43
It'd be more efficient to close the FDs rather than re-opening them to /dev/null: <&- 1<&- 2<&- –  Charles Duffy May 16 '12 at 16:30

I used at for this, as it is really starting an independent process.

    `echo "the command"|at now`;
share|improve this answer
in some situations this is absolutely the best solution. it was the only one that worked for me to release a "sudo reboot" ("echo 'sleep 3; sudo reboot' | at now") from a webgui AND finish rendering the page .. on openbsd –  Kaii Aug 13 '09 at 18:47

On linux you can do the following:

$cmd = 'nohup nice -n 10 /usr/bin/php -c /path/to/php.ini -f /path/to/php/file.php action=generate var1_id=23 var2_id=35 gen_id=535 > /path/to/log/file.log & printf "%u" $!';
$pid = shell_exec($cmd);

This will execute the command at the command prompty and then just return the PID, which you can check for > 0 to ensure it worked.

This question is similar: Does PHP have threading?

share|improve this answer

php-execute-a-background-process has some good suggestions. I think mine is pretty good, but I'm biased :)

share|improve this answer
Nice answer in that thread :) –  dcousineau Oct 21 '08 at 22:57

In Linux, you can start a process in a new independent thread by appending an ampersand at the end of the command

mycommand -someparam somevalue &

In Windows, you can use the "start" DOS command

start mycommand -someparam somevalue
share|improve this answer
On Linux, the parent can still block until the child has finished running if it's trying to read from an open file handle held by the subprocess (ie. stdout), so this isn't a complete solution. –  Charles Duffy May 16 '12 at 16:31

the right way(!) to do it is to

  1. fork()
  2. setsid()
  3. execve()

fork forks, setsid tell the current process to become a master one (no parent), execve tell the calling process to be replaced by the called one. so that the parent can quit without affecting the child.

   // child becomes the standalone detached process

 // parent's stuff
share|improve this answer
The problem with pcntl_fork() is that you are not supposed to use it when running under a web server, as the OP does (besides, the OP have tried this already). –  Guss May 11 '10 at 15:13

I used this...

 * Asynchronously execute/include a PHP file. Does not record the output of the file anywhere.  
 * Relies on the PHP_PATH config constant.
 * @param string $filename  file to execute
 * @param string $options   (optional) arguments to pass to file via the command line
function asyncInclude($filename, $options = '') {
    exec(PHP_PATH . " -f {$filename} {$options} >> /dev/null &");

(where PHP_PATH is a const defined like define('PHP_PATH', '/opt/bin/php5') or similar)

It passes in arguments via the command line. To read them in PHP, see argv.

share|improve this answer

The only way that I found that truly worked for me was:

shell_exec('./myscript.php | at now & disown')
share|improve this answer
'disown' is a Bash built-in and doesn't work with shell_exec() this way. I tried shell_exec("/usr/local/sbin/command.sh 2>&1 >/dev/null | at now & disown") and all I get is: sh: 1: disown: not found –  Thomas Daugaard Jan 15 '13 at 12:52

You can also run the php script as daemon or cronjob... #!/usr/bin/php -q

share|improve this answer

Use a named fifo.

mkfifo trigger
while true; do
    read < trigger

Then whenever you want to start the long running task, simply write a newline (nonblocking to the trigger file.

As long as your input is smaller than PIPE_BUF and it's a single write() operation, you can write arguments into the fifo and have them show up as $REPLY in the script.

share|improve this answer

There are another solution in the PHPClasses site.

I've adapted it so it is usable from web too. You can find it in my github (https://github.com/mmarquez/php-thread).

It can handle the creation of various children processes. I hope it can help you.

share|improve this answer

Your Answer


