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/writableproc_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
Oauth Implementation in Netsuite Using PHP
Jquery Mobile: Sending Data from One Page to the Another
Cakephp Database Connection "Mysql" Is Missing, or Could Not Be Created
Function Ereg_Replace() Is Deprecated - How to Clear This Bug
Continuing Overflowed Text in a Different Div
Passing Variables from PHP to JavaScript
PHP Tree Structure for Categories and Sub Categories Without Looping a Query
Yii2 Disable Bootstrap Js, Jquery and CSS
PHP Function Imagettftext() and Unicode
Yii2 Translation Does Not Work
In PHP, How to Check If a Function Exists
Use Curly Brackets to Structure Code in PHP
PHP - Merge Two Arrays (Same-Length) into One Associative