I have to start a NodeJS server from my script in PHP without waiting for it. To get started the NodeJS server I use.
$command = "cd /d " . $row["pathServer"] . " && node server";
exec($command, $output);
but it doesn't work because the webserver waits until the command is finished. How can I separate the two processes?
Just redirect the stdout of command to a file, if you want to see it later. But if you don't want it, just redirect to /dev/null
$command = "cd /d " . $row["pathServer"] . " && node server > /dev/null &";
exec($command);
Related
I try to execute a .php script with the shell_exec() function on a 1&1 Linux shared Webserver (debian GNU/Linux 8 distribution).
private function callAsyncSkript(){
// Asynchron Zipping over executing a Script in a new process.
if (substr(php_uname(), 0, 7) == "Windows"){
$cmd = "start /B php .\src\Core\Services\AsynchronZip.php fileids=".$this->idQuery . " fulllink=".$this->uri;
pclose(popen($cmd, "r"));
}
else {
$cmd = "/usr/bin/php7.2-cli ".getcwd()."/src/Core/Services/AsynchronZip.php fileids=".$this->idQuery . " fulllink=".$this->uri;
shell_exec("/usr/bin/nohup ".$cmd." >/dev/null 2>&1 &"." | at now");
//shell_exec("/usr/bin/nohup ".$cmd." >/dev/null 2>&1 &");
}
}
The "/usr/bin/nohup " addition donĀ“t help to execute the script asynchron,
if iam using " | at now" the script will not be executed.
Are there some special settings i have to set or are there other options for an asynchron execution over the commandline?
I found out that the only shell available to me is a rssh. Is it possible that she is the mistake.
I have MAMP installed and am running a php script to execute external programs (jar and exe). Everything works perfectly on my local machine.
However when I put it all on the AWS instance, it just ignores the pclose(popen(...)) line. I get both log messages and no errors.
$command = 'start /B cmd /C '.$this->getCommand().' >NUL 2>NUL';
$this->Log.debug('executing command : '.$command);
pclose(popen($command, 'r'));
$this->Log.debug('command sent');
I'm thinking it might be a permissions issue of some sort? But I've checked the php.ini and the Apache permissions and everything looks good. Php is not being told to ignore the popen command.
Update:
I created a test.bat file in the same location
echo Hello, World > donald.txt
and this executes when called from php, so now I know the pclose(popen()) is working. The command I am trying to execute is java - jar ... so it must be something to do with permissions running java?
So this works:
start /B cmd /C D:/programs/test.bat >NUL 2>NUL
and this does not:
start /B cmd /C java -Xmx2048m -jar "D:\programs\program.jar" -pm XXX_YYY -t FULL -flag1 -flag2 -k 23 >NUL 2>NUL
Remove everything that is unnecessary, to make your command look like this:
$command = 'start /B ' . $this->getCommand();
you don't need any redirection as start /b will start program without new window.
I have the following:
$cmd = 'start /b php {$file} {$bid}';
pclose(popen($cmd, 'r'));
And it works on windows perfectly.
BTW, for Linux-based machine you need to run command like this:
$command = $this->getCommand() . ' &';
to make one script works on windows and Linux you need something like this:
$command = $this->getCommand() . ' &';
if (false !== stripos(PHP_OS, 'win')) {
$command = 'start /B ' . $this->getCommand();
}
$this->Log.debug('executing command : '.$command);
$p = popen($command, 'r');
sleep(10); //we will give some time for process to start
pclose($p);
$this->Log.debug('command sent');
UPDATE: in the chat we've figured out that the problem was with path to java.exe. Apache was unable to find java executable. so the solution was to specify absolute path to java.exe:
$command = 'start /B C:/Progra~1/Java/jre1.8.0_102/bin/java.exe -Xmx2048m -jar "C:/programs/some-jar-file.jar" -?';
I want to convert this PHP script which works great on a Unix system into a script for Windows.
I don't know how to rewrite it. Can someone help me?
Here is the script:
$cmd = 'nohup sudo -u '.$user.' bash -c "cd ' .
escapeshellarg($path) . '; VVERBOSE=true QUEUE=' .
escapeshellarg($queue) . ' APP_INCLUDE=' .
escapeshellarg($bootstrap_path) . ' INTERVAL=' .
escapeshellarg($interval) . ' CAKE=' .
escapeshellarg(CAKE) . ' COUNT=' . $count .
' php ./resque.php';
$cmd .= ' > '. escapeshellarg($log_path).' 2>&1" >/dev/null 2>&1 &';
passthru($cmd);
passthru is a method in PHP see http://php.net/manual/en/function.passthru.php
Do you know what the script does? Maybe reverse engineer it into windows batch script?
From the looks of it, the script came from a *nix system it:
execute a command as another user
change the current directory
set environment variables
calls a PHP script directly from the PHP interpreter and dumps the log into a file, and pipes the stderrs to /dev/null
That script is imo, is impossible to "covert" to Windows batch script (since Windows != POSIX), you need to rewrite it.
I have a QNAP box, that runs a flavor of linux and I am having problems getting the PID of a process using a php script. What I have so far:
$command = "PATH=$PATH:/share/MD0_DATA/.qpkg/Optware/bin: nohup /opt/bin/plowdown -o /share/MD0_DATA/Qdownload/plowshare http://www.megaupload.com/?d=m7duotr1 2> /share/MD0_DATA/Qdownload/plowshare/outputeeds.txt > /dev/null &";
exec($command, $out);
$result = $out[0];
echo $result;
If I run the command through PUTTY, I get:
[~] # nohup /opt/bin/plowdown -o /share/MD0_DATA/Qdownload/plowshare http://www.megaupload.com/?d=m7duotr1 2> /share/MD0_DATA/Qdownload/plowshare/outputteeds.txt > /dev/null &
22526
What am I doing wrong?
Thanks,
Cristian.
The shell does not normally print the PID of a process it starts in background, unless it's interactive. Otherwise, you would get tons of output during bootup just from the PIDs of all the processes that get started.
So you need to make the shell print the PID. Do
exec("(PATH=$PATH:/share/MD0_DATA/.qpkg/Optware/bin: " .
"nohup /opt/bin/plowdown -o /share/MD0_DATA/Qdownload/plowshare " .
"http://www.megaupload.com/?d=m7duotr1 2> " .
"/share/MD0_DATA/Qdownload/plowshare/outputeeds.txt > /dev/null &);" .
"echo $$;", $out);
http://nl2.php.net/manual/en/function.getmypid.php
I have a command I want to run, but I do not want PHP to sit and wait for the result.
<?php
echo "Starting Script";
exec('run_baby_run');
echo "Thanks, Script is running in background";
?>
Is it possible to have PHP not wait for the result.. i.e. just kick it off and move along to the next command.
I cant find anything, and not sure its even possible. The best I could find was someone making a CRON job to start in a minute.
From the documentation:
In order to execute a command and have it not hang your PHP script while
it runs, the program you run must not output back to PHP. To do this,
redirect both stdout and stderr to /dev/null, then background it.
> /dev/null 2>&1 &
In order to execute a command and have
it spawned off as another process that
is not dependent on the Apache thread
to keep running (will not die if
somebody cancels the page) run this:
exec('bash -c "exec nohup setsid your_command > /dev/null 2>&1 &"');
You can run the command in the background by adding a & at the end of it as:
exec('run_baby_run &');
But doing this alone will hang your script because:
If a program is started with exec function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.
So you can redirect the stdout of the command to a file, if you want to see it later or to /dev/null if you want to discard it as:
exec('run_baby_run > /dev/null &');
This uses wget to notify a URL of something without waiting.
$command = 'wget -qO- http://test.com/data=data';
exec('nohup ' . $command . ' >> /dev/null 2>&1 & echo $!', $pid);
This uses ls to update a log without waiting.
$command = 'ls -la > content.log';
exec('nohup ' . $command . ' >> /dev/null 2>&1 & echo $!', $pid);
I know this question has been answered but the answers i found here didn't work for my scenario ( or for Windows ).
I am using windows 10 laptop with PHP 7.2 in Xampp v3.2.4.
$command = 'php Cron.php send_email "'. $id .'"';
if ( substr(php_uname(), 0, 7) == "Windows" )
{
//windows
pclose(popen("start /B " . $command . " 1> temp/update_log 2>&1 &", "r"));
}
else
{
//linux
shell_exec( $command . " > /dev/null 2>&1 &" );
}
This worked perfectly for me.
I hope it will help someone with windows. Cheers.
There are two possible ways to implement it.
The easiest way is direct result to dev/null
exec("run_baby_run > /dev/null 2>&1 &");
But in case you have any other operations to be performed you may consider ignore_user_abort
In this case the script will be running even after you close connection.
"exec nohup setsid your_command"
the nohup allows your_command to continue even though the process that launched may terminate first. If it does, the the SIGNUP signal will be sent to your_command causing it to terminate (unless it catches that signal and ignores it).
On Windows, you may use the COM object:
if(class_exists('COM')) {
$shell = new COM('WScript.Shell');
$shell->Run($cmd, 1, false);
}
else {
exec('nohup ' . $cmd . ' 2>&1 &');
}