Invoke External Shell Script from PHP and Get Its Process Id

Invoke external shell script from PHP and get its process ID

$command =  'yourcommand' . ' > /dev/null 2>&1 & echo $!; ';

$pid = exec($command, $output);

var_dump($pid);

Starting a Windows process in PHP and get it's PID?

I managed to get it. I used proc_open to execute, which returns the PPID of the game server ran (the cmd.exe executable).

As start /b exit's the cmd.exe once it has executed the program, the only thing that should have that PPID is the game server, thus the rest of it to find the PID was relatively easy.

This also works when multiple instances are made at once, and when multiple instances are already running.

This is the end script to get the PID with proc_open, if anyone else wonders across this thread and may happen to need it:

<?php

$startDir = "C:/Torque/My Projects/Grim/game";
$runExe = "$startDir/Grimwood.exe";
$envars = " -dedicated -mission \"core/levels/Empty Terrain.mis\"";

$runPath = $runExe . $envars;

chdir($startDir);

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

if ( is_resource( $prog = proc_open("start /b " . $runPath, $descriptorspec, $pipes, $startDir, NULL) ) )
{
$ppid = proc_get_status($prog)['pid'];
}
else
{
echo("Failed to execute!");
exit();
}

$output = array_filter(explode(" ", shell_exec("wmic process get parentprocessid,processid | find \"$ppid\"")));
array_pop($output);
$pid = end($output);

echo("\nProcess ID: $pid ; Parent's Process ID: $ppid\n");

// returns right process
$task = shell_exec("tasklist /fi \"PID eq $pid\"");
echo("\n\nProcess: \n$task\n\n");

// returns no process found
$task = shell_exec("tasklist /fi \"PID eq $ppid\"");
echo("\n\nParent Process: \n$task\n\n");

?>

How to execute shell from php script

Depending on if you need the output of the script there are different approaches.

  • exec executes a command and return output to the caller.

  • passthru function should be used in place of exec when the output from the Unix command is binary data which needs to be passed directly back to the browser.

  • system executes an external program and displays the output, but only the last line.

  • popen — creates a new process that is unidirectional read/writable

  • proc_open — creates a new process that supports bi-directional read/writable

For your scrapy script I would use a combination of popen and pclose as I don't think you need the script output.

pclose(popen("scrapy crawl example -a siteid=$id > /dev/null &", 'r'));

Start and monitor process with exec()

I've now worked around this issue by writing the exit code to a log file once the long running script is finished. By adding this to the initial command, I can "fire and forget" the process and check the status code from the log file later.

This is the command (wasn't really easy to come by):

$pid = exec('('.
// don't listen to the hangup signal
// invoke the script and write the output to the log file
"nohup $script >> $logFile 2>&1; ".
// when the script is finished, write the exit code to the log file
'echo "Exit code $?" >> '.$logFile.
// discard the output of the `()' part so exec() doesn't
// wait for the process to be finished,
// then send the `()' part to the background
') > /dev/null 2>&1 & '.
// immediately return the process id of the background process
'echo $!');

Monitoring the running process works well using the kill -0 method with the process ID:

// true if the process is still running
exec("kill -s 0 $pid 1>/dev/null 2>&1; echo $?") === '0'

This requires the PHP/Apache user to be able to send a kill signal to the process but this requirement should be met because the process was launched by the same user that now tries to monitor it.

Once the process is no longer running, I can determine if it was successful by checking the log file.

PHP execute external script without waiting, while passing variables

You test use it

exec("php -f ./process.php var1 var2 > /dev/null 2>/dev/null &"); 

And if you like get these variables values can acces with global variable $argv. If you print this var show same:

print_r($argv);

Array
(
[0] => process.php
[1] => var1
[2] => var2
)

How to get pid of the process that run in background exec by shell in php

If you want the pid in bash, you can do use the ! special parameter to get the pid of the most recently backgrounded process:

bash -c 'sleep 10 & echo $!'

I don't know exactly how php spawns external processes, but I imagine you'd be able to capture the echo output here, just by running the above shell command.

Asynchronous shell exec in PHP

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:

" > /dev/null 2>/dev/null &"

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 &"

How to check whether specified PID is currently running without invoking ps from PHP?

If you are on Linux, try this :

if (file_exists( "/proc/$pid" )){
//process with a pid = $pid is running
}


Related Topics



Leave a reply



Submit