Shell_Exec() Timeout Management & Exec()

shell_exec() timeout management & exec()

I would suggest you look into using proc_open. You can configure it to return a stream resource, manually keep a timer, and if the timer expires before the process completes, you can terminate it with proc_terminate. If it does complete before the timer expires, then you can use proc_close then stream_get_contents to grab the data that would have otherwise been written to stdout.

See http://www.php.net/manual/en/function.proc-open.php

set time limit on java code execution through shell_exec

You can do it in 3 ways:

1) Call pcntl_fork in PHP and check the timeout in parent process. Kill it if it exceeds using linux kill command.

2) Include timeout in a bash script that you will invoke using shell_exec, see this example:
http://www.bashcookbook.com/bashinfo/source/bash-4.0/examples/scripts/timeout3

3) Use proc_open / proc_terminate functions

Personally I would go with number 3, it's the cleanest. If you need quick and dirty, use number 2.

PHP set timeout for script with system call, set_time_limit not working

You can use a combination of "--timeout" and time(). Start off by figuring out how much time you have total, and lower the --timeout as your script runs.

For example:

$endtime = time()+15;
foreach( $url as $key => $value){
$timeleft = $endtime - time();
if($timeleft > 0) {
$wget = "wget -t 1 --timeout $timeleft $otherwgetflags $value";
print "running $wget<br>";
system($wget);
} else {
print("timed out!");
exit(0);
}
}

Note: if you don't use -t, wget will try 20 times, each waiting --timeout seconds.

Here's some example code using proc_open/proc_terminate (@Josh's suggestion):

$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$pipes = array();

$endtime = time()+15;
foreach( $url as $key => $value){
$wget = "wget $otherwgetflags $value";
print "running $wget\n";
$process = proc_open($wget, $descriptorspec, $pipes);
if (is_resource($process)) {
do {
$timeleft = $endtime - time();
$read = array($pipes[1]);
stream_select($read, $write = NULL, $exeptions = NULL, $timeleft, NULL);
if(!empty($read)) {
$stdout = fread($pipes[1], 8192);
print("wget said--$stdout--\n");
}
} while(!feof($pipes[1]) && $timeleft > 0);
if($timeleft <= 0) {
print("timed out\n");
proc_terminate($process);
exit(0);
}
} else {
print("proc_open failed\n");
}
}

Best way to manage long-running php script?

Certainly it can be done with PHP, however you should NOT do this as a background task - the new process has to be dissociated from the process group where it is initiated.

Since people keep giving the same wrong answer to this FAQ, I've written a fuller answer here:

http://symcbean.blogspot.com/2010/02/php-and-long-running-processes.html

From the comments:

The short version is shell_exec('echo /usr/bin/php -q longThing.php | at now'); but the reasons "why", are a bit long for inclusion here.

Update +12 years

While this is still a good way to invoke a long running bit of code, it is good for security to limit or even disable the ability of PHP in the webserver to launch other executables. And since this decouples the behaviour of the log running thing from that which started it, in many cases it may be more appropriate to use a daemon or a cron job.



Related Topics



Leave a reply



Submit