exec() with timeout

exec-timeout 0 0 means
exec-timeout vs session-timeout
cisco exec-timeout best practice
exec-timeout 0 1
php exec("timeout
how to set ssh timeout on cisco switch
exec-timeout command what do the 5 and 0 represent
console timeout 0

I'm looking for a way to run a PHP process with a timeout. Currently I'm simply using exec(), but it does not provide a timeout option.

What I also tried is opening the process using proc_open() and using stream_set_timeout() on the resulting pipe, but that didn't work either.

So, is there any way to run a command (a PHP command to be precise) with a timeout? (PS: This is for cases where the max_execution_time limit fails, so no need to suggest that.)

(By the way, I also need to retrieve the return code of the process.)

I've searched a bit on this topic and came to conclusion that in some case (if you are using linux) you can use 'timeout' command. It's pretty flexible

Usage: timeout [OPTION] DURATION COMMAND [ARG]...
  or:  timeout [OPTION]

in my particular case I'm trying to run sphinx indexer from PHP, kinda migration data script so I need to reindex my sphinx documents

exec("timeout {$time} indexer --rotate --all", $output);

Then I'm going to analyze output and decide to give it one more try, or throw an exception and quit my script.

exec() with timeout, I'm looking for a way to run a PHP process with a timeout. Currently I'm simply using exec() , but it does not provide a timeout option. What I also  It is common to have a session time in a corporate security policy. In a simple way of putting it, the exec-timeout will terminate an exec session after the session has been idle for the configured exec-timeout time. The default is 10 minutes. An absolute timeout however is a the maximum amount of time a single session can remain established.

I found this on php.net that I think can do what you want

<?php 
function PsExecute($command, $timeout = 60, $sleep = 2) { 
    // First, execute the process, get the process ID 

    $pid = PsExec($command); 

    if( $pid === false ) 
        return false; 

    $cur = 0; 
    // Second, loop for $timeout seconds checking if process is running 
    while( $cur < $timeout ) { 
        sleep($sleep); 
        $cur += $sleep; 
        // If process is no longer running, return true; 

       echo "\n ---- $cur ------ \n"; 

        if( !PsExists($pid) ) 
            return true; // Process must have exited, success! 
    } 

    // If process is still running after timeout, kill the process and return false 
    PsKill($pid); 
    return false; 
} 

function PsExec($commandJob) { 

    $command = $commandJob.' > /dev/null 2>&1 & echo $!'; 
    exec($command ,$op); 
    $pid = (int)$op[0]; 

    if($pid!="") return $pid; 

    return false; 
} 

function PsExists($pid) { 

    exec("ps ax | grep $pid 2>&1", $output); 

    while( list(,$row) = each($output) ) { 

            $row_array = explode(" ", $row); 
            $check_pid = $row_array[0]; 

            if($pid == $check_pid) { 
                    return true; 
            } 

    } 

    return false; 
} 

function PsKill($pid) { 
    exec("kill -9 $pid", $output); 
} 
?>

exec-timeout, What is the purpose for command exec timeout 0 0? Exec with timeout in VBScript. GitHub Gist: instantly share code, notes, and snippets.

You could fork() and then exec() in one process and wait() non-blocking in the other. Also keep track of the timeout and kill() the other process if it does not finish in time.

Configuring the Terminal Server for Telnet Access, which means that the console line will logoff when inactivity at this line reaches 10 minutes. exec-timeout 10 0 10 is the minutes and 0 is the seconds. This is the default Cisco value. I'm guessing here that the command "timeout login response 0" might be the default value so try the exec-timeout command with response 0 and see how things go.

The timeout {$time} command solution does not work properly when it's called from a PHP script. In my case, with a ssh command to a wrong server (rsa key not found, and the server ask for a password), the process still alive after the defined timeout.

However I've found a function that works fine here:

http://blog.dubbelboer.com/2012/08/24/execute-with-timeout.html

C&P:

/**
 * Execute a command and return it's output. Either wait until the command exits or the timeout has expired.
 *
 * @param string $cmd     Command to execute.
 * @param number $timeout Timeout in seconds.
 * @return string Output of the command.
 * @throws \Exception
 */
function exec_timeout($cmd, $timeout) {
  // File descriptors passed to the process.
  $descriptors = array(
    0 => array('pipe', 'r'),  // stdin
    1 => array('pipe', 'w'),  // stdout
    2 => array('pipe', 'w')   // stderr
  );

  // Start the process.
  $process = proc_open('exec ' . $cmd, $descriptors, $pipes);

  if (!is_resource($process)) {
    throw new \Exception('Could not execute process');
  }

  // Set the stdout stream to none-blocking.
  stream_set_blocking($pipes[1], 0);

  // Turn the timeout into microseconds.
  $timeout = $timeout * 1000000;

  // Output buffer.
  $buffer = '';

  // While we have time to wait.
  while ($timeout > 0) {
    $start = microtime(true);

    // Wait until we have output or the timer expired.
    $read  = array($pipes[1]);
    $other = array();
    stream_select($read, $other, $other, 0, $timeout);

    // Get the status of the process.
    // Do this before we read from the stream,
    // this way we can't lose the last bit of output if the process dies between these     functions.
    $status = proc_get_status($process);

    // Read the contents from the buffer.
    // This function will always return immediately as the stream is none-blocking.
    $buffer .= stream_get_contents($pipes[1]);

    if (!$status['running']) {
      // Break from this loop if the process exited before the timeout.
      break;
    }

    // Subtract the number of microseconds that we waited.
    $timeout -= (microtime(true) - $start) * 1000000;
  }

  // Check if there were any errors.
  $errors = stream_get_contents($pipes[2]);

  if (!empty($errors)) {
    throw new \Exception($errors);
  }

  // Kill the process in case the timeout expired and it's still running.
  // If the process already exited this won't do anything.
  proc_terminate($process, 9);

  // Close all streams.
  fclose($pipes[0]);
  fclose($pipes[1]);
  fclose($pipes[2]);

  proc_close($process);

  return $buffer;
}

Basic Cisco Terminal Access, Which statement describes the effect of the exec timeout 30 command? GNU/Linux comes timeout command. It runs a command with a time limit. One can also use Perl or bash shell to run a command and have it timeout after N seconds. This page explains how to start a command, and kill it if the specified timeout expires.

(Disclaimer: I was surprised to find no good solution for this, then I browsed the proc documentation and found it pretty straight forward. So here is a simple proc answer, that uses native functions in a way that provides consistent results. You can also still catch the output for logging purposes.)

The proc line of functions has proc_terminate ( process-handler ), which combined with proc_get_status ( process-handler ) getting the "running" key, you can while loop with sleep to do a synchronous exec call with a timeout.

So basically:

$ps = popen('cmd');
$timeout = 5; //5 seconds
$starttime = time();
while(time() < $starttime + $timeout) //until the current time is greater than our start time, plus the timeout
{
    $status = proc_get_status($ps);
    if($status['running'])
        sleep(1);
    else
        return true; //command completed :)
}

proc_terminate($ps);
return false; //command timed out :(

Which statement describes the effect of exec-timeout 30 command , exec-timeout. To configure the inactive session timeout on the console port or the virtual terminal, use the exec-timeout command. To revert to the default,  (↑ Back to exec attributes) timeout. The maximum time the command should take. If the command takes longer than the timeout, the command is considered to have failed and will be stopped. The timeout is specified in seconds. The default timeout is 300 seconds and you can set it to 0 to disable the timeout. Default: 300 (↑ Back to exec attributes) tries

exec-timeout.html, What I want to do is run this command through exec(), kill the process after 30 seconds, but be able to get the output that was generated in those 30 seconds. The proc line of functions has proc_terminate ( process-handler ), which combined with proc_get_status ( process-handler ) getting the "running" key, you can while loop with sleep to do a synchronous exec call with a timeout.

Exec() with timeout, but also with output - PHP, Prior to Go 1.7, ending an external process based on a timeout took a bit of work. With the move of the context package into the standard library,  Starting, version: 2.0.15.11 Loading config Loading games Loading C:\Hakchi\hakchi2_215b_debug\data escarts.xml Listening port 1023 XML loading done, 2149 roms total Saving config Saving config clovershell connected clovershell read timeout at com.clusterrr.clovershell.ClovershellConnection.Execute(String command, Stream stdin, Stream stdout, Stream stderr, Int32 timeout, Boolean

Go: Timeout Commands with os/exec CommandContext, exec() will only run assertions you've chained once, and will not retry. Timeouts. cy.exec() can time out waiting for the system command  Timeout parameters. curl has two options: --connect-timeout and --max-time. Quoting from the manpage:--connect-timeout <seconds> Maximum time in seconds that you allow the connection to the server to take. This only limits the connection phase, once curl has connected this option is of no more use.

Comments
  • start timer. put process in infinite loop, checking the timer, time-out when needed.
  • Working great :)
  • This looks like a reasonable approach, but how can one get the return code in this case?
  • Are you referring to the pcntl_ functions here?
  • @NikiC: Yes, I think that's what they are called in PHP.
  • I've found there is one problem with this code. Although it is true that calls to stream_get_contents($pipes[1]) will return immediately because that pipe was set to non-blocking, the LAST call which is stream_get_contents($pipes[2]) will actually block until the whole process exits because the stderr pipe was never set to non blocking. This defeats the whole purpose of being able to return control to the caller after the timeout. The solution is simple: Add stream_set_blocking($pipes[2], 0); after the first one above
  • But manual says proc_get_status and proc_terminate works with resource returned by proc_open only, not popen?
  • for slightly more precision, you could replace time() with microtime(true) and also sleep to some smaller interval like usleep(100000) for 100ms of sleep