3

I am using this code on Ubuntu 13.04,

$cmd = "sleep 20 &> /dev/null &";
exec($cmd, $output);

Although it actually sits there for 20 seconds and waits :/ usually it works fine when using & to send a process to the background, but on this machine php just won't do it :/
What could be causing this??

Goulash
  • 3,708
  • 6
  • 29
  • 48

3 Answers3

8

Try

<?PHP
$cmd = '/bin/sleep';
$args = array('20');

$pid=pcntl_fork();
if($pid==0)
{
  posix_setsid();
  pcntl_exec($cmd,$args,$_ENV);
  // child becomes the standalone detached process
}

echo "DONE\n";

I tested it for it works. Here you first fork the php process and then exceute your task.

Or if the pcntl module is not availabil use:

<?PHP

$cmd = "sleep 20 &> /dev/null &";
exec('/bin/bash -c "' . addslashes($cmd) . '"');
GreenRover
  • 1,486
  • 1
  • 14
  • 33
  • always add a description of you answer. – Arash Milani Jan 19 '13 at 07:45
  • `CMD=> nohup sleep 20 &> /dev/null & This page was run in 20.082479000092 seconds array(0) { }` didn't work :( – Goulash Jan 19 '13 at 07:49
  • Changed my answer to a tested version. – GreenRover Jan 19 '13 at 08:07
  • the only problem is that it requires having a version of PHP compiled with pcntl enabled, which I don't :( – Goulash Jan 21 '13 at 22:40
  • Changed my answer againe. Sorry but your solution is an bad idea because it is a realy huge securety lag. – GreenRover Jan 22 '13 at 07:37
  • Well it's slow, but not too much of a security issue since only localhost can login and the webserver user is custom and has very little access. But your solution worked great :D why does -c make it work? – Goulash Jan 22 '13 at 09:33
  • Mats explained it well the "&> /dev/null &" is parsed by the shell. Why i have done "bash -c" is let the Born Againe Shell interprete it. – GreenRover Jan 22 '13 at 09:47
  • Ah, I see, so it wasn't being sent to bash :( – Goulash Jan 22 '13 at 10:26
  • @GreenRover I wish I could upvote your answer more than once... Solution with `-c` & `addslashes` is ONLY thing that works now, it seems. No other answer which can be googled is working. Did not tried the `pcntl`, though. – hijarian Feb 15 '13 at 12:48
1

The REASON this doesn't work is that exec() executes the string you're passing into it. Since & is interpreted by the shell as "execute in the background", but you don't execute a shell in your exec call, the & is just passed along with 20 to the /bin/sleep executable - which probably just ignores that.

The same applies to the redirection of output, since that is also parsed by the shell, not in exec.

So, you either need to find a way to fork your process (as described above), or a way to run the subprocess as a shell.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • This is not true. `exec()` does launch a shell. One way you can detect the presence of the shell is by executing a command that the shell will consider invalid. For example, `echo "" | php` will print something like "sh: NonExistentCommand: command not found". The `sh:` portion is coming from `sh` (`/bin/sh`) – rinogo Aug 25 '20 at 02:43
0

My workaround to do this on ubuntu 13.04 with Apache2 and any version of PHP:
libssh2-php, I just used nohup $cmd & inside a local SSH session using PHP and it ran it just fine the background, of course this requires putting certain security protocols in place, such as enabling SSH access for the webserver user, so it would have exec-like permissions then only allowing localhost to login to the webserver ssh account.

Goulash
  • 3,708
  • 6
  • 29
  • 48