I have a python script that picks an URL as parameter and it fetch some data (normally it takes 30 seconds to finish) and creates a file with it. What I want is to be able to call the script from a web (I thought about doing it with PHP but i don't mind) and just get the file path (which is printed at the begining of the script process) and leave the script running in background.
how can i do this? which is the best way?
Note: I'm using a raspberry pi as a web server and the python file is located in /var/www/
php can execute system commands using the command system().
To execute a python script, you can use this command:
system('/path/to/python /path/to/test.py');
To leave it running in the background, use &:
system('/path/to/python /path/to/test.py &');
If you want to start the script in the background but still get the first lines of output, I would redirect the output to a file:
system('/path/to/python /path/to/test.py >/var/www/unique_file.txt &');
sleep(500); // Script has printed the file path now
$output = file_get_contents("unique_file.txt");
Related
I have 2 websites, hosted on 2 different servers. They are kind of interlinked. Sometimes I just do stuff on Website-1 and run a script on Website-2. Like I edited something on Website-1 and now I want to run a script on Website-2 to update accordingly on it's server.
Till now I am using following code on website 1.
$file = file_get_contents('Website-2/update.php');
But the problem with this is that my Website-1 server script stops running and wait for the file to return some data. And I don't wanna do anything with that data. I just wanted to run the script.
Is there a way where I can do this in a better way or tell PHP to move to next line of code.
If you want to call the second site without making your user wait for a response,
I would recommend using a message queue.
Site 1 request would put a message to the queue.
Cron job to check queue and run update on site 2 when message exists.
Common queues apps to look at:
[https://aws.amazon.com/sqs/?nc2=h_m1][1]
[https://beanstalkd.github.io/][2]
[https://www.iron.io/mq][3]
[1]: https://aws.amazon.com/sqs/?nc2=h_m1
[2]: https://beanstalkd.github.io/
[3]: https://www.iron.io/mq
What you're trying to achieve is called a web hook and should be implemented with proper authentication, so that not anybody can execute your scripts at any time and overload your server.
On server 2 you need to execute your script asynchronously via workers, threads, message queues or similar.
You can also run the asynchronous command on your server 1. There are many ways to achieve this. Here are some links with more on this.
(Async curl request in PHP)
(https://segment.com/blog/how-to-make-async-requests-in-php/)
Call your remote server as normal. But, In the PHP script you normally call, Take all the functionality and put it in a third script. Then from the old script call the new one with (on Linux)
exec('php -f "{path to new script}.php" $args > /dev/null &');
The & at the end makes this a background or non-blocking call. Because you call it from the remote sever you don't have to change anything on the calling server. The php -f runs a php file. The > /dev/null sends the output from that file to the garbage.
On windows you can use COM and WScript.Shell to do the same thing
$WshShell = new \COM('WScript.Shell');
$oExec = $WshShell->Run('cmd /C php {path to new script}.php', 0, false);
You may want to use escapeshellarg on the filename and any arguments supplied.
So it will look like this
Server1 calls Server2
Script that was called (on Server2) runs exec and kicks off a background job (Server2) then exits
Server1 continues as normal
Server2 continues the background process
So using your example instead of calling:
file_get_contents('Website-2/update.php');
You will call
file_get_contents('Website-2/update_kickstart.php');
In update_kickstart.php put this code
<?php
exec('php -f "{path}update.php" > /dev/null &');
Which will run update.php as a separate background (non-blocking) call. Because it's non-blocking update_kickstart.php will finish and return to searver1 which can go about it's business and update.php will run on server2 independantly
Simple...
The last note is that file_get_contents is a poor choice. I would use SSH and probably PHPSecLib2.0 to connect to server2 and run the exec command directly with a user that has access only to that file(Chroot it or something similar). As it is anyone can call that file and run it. With it behind a SSH login it's protected, with it Chrooted that "special" user can only run that one file.
I have a php webpage located on Webserver1, which is from Host1.
I also have a bash script located in Gameserver1 which is from Host2.
Is there any way to send a command from Webserver1 to Gameserver1 to execute the bash file? The webpage and file are on different VPSs. Both are running Debian 7.
The script is literally one line, to execute a java command via a screen, so the server can start if a player notices it's down. The command's available already so it doesn't need to be a secure way of hiding what the command is.
There are 2 ways I can think of. either create a bash file in Webserver1 that connects through ssh and executes the bash script you need on Gameserver1. then run it through php with exec() command.
Or you can create a php file in Gameserver1 that uses exec() to execute the bash script you need on Gameserver1 and call it using file_get_contents() on Webserver1, which is not that secure since anyone can call that file and run your script.
I need to run a Python script in the background after being called from a PHP file. The PHP file should continue to run independently of the Python script (i.e. it shouldn't hang waiting for the Python script to finish processing, but should instead carry on processing itself).
The Python script takes one argument and produces no output (it merely processes some data in the background), then exits. I'm running Python 2.6, PHP 5.2.6, and Ubuntu 9.04.
You could use exec() to kick off the Python interperator and have it send its output to either a file or to /dev/null with redirection. Using the & operator in the exec call will cause the command to be started and PHP to continue without waiting for a result.
http://www.developertutorials.com/tutorials/php/running-background-processes-in-php-349/ goes into more detail.
PHP Process Control can be used for this. The proc_open command can be used to start a process. You can later check up on it, read it's output etc.
View the manual entry: http://www.php.net/manual/en/function.proc-open.php and search around google for PHP Process Control
I'm guessing the PHP file is called via Apache, in which case you won't be able to fork(). You should make your Python script daemonize. Check out python-daemon.
You could use:
<?php
shell_exec('./test.sh &');
?>
where ./test.sh should be the execution line to your script
I want initiate one php page as background process from another php page.
Use popen():
$command = 'php somefile.php';
pclose(popen($command,'r'));
This launches somefile.php as a background process.
This is a technique I used to get around restrictions applied by my webhost (who limited cronjobs to 15 minutes of execution time, so my backup scripts would always timeout).
exec( 'php somefile.php | /dev/null &' );
The breakdown of this line is:
exec() - PHP reference Runs the specified command, as if from the Linux Command Line.
php somefile.php: Invokes PHP to open, and run, somefile.php. This is the same behaviour as what would happen if that file was accessed through a web browser.
| ("pipe") - Sends the output of the proceeding command to a specified target. In this instance, it would "pipe" the content which would normally be read by the web browser accessing the file.
/dev/null - A blackhole. No, not kidding. It is a place where you send output if you just want it to disappear.
& - Appending this character to the end of a Linux command means "Do not wait - Send this to the background and continue."
So, in summary, the provided code will execute a PHP script, return no output, and not wait for it to finish before continuing onto the next line.
(And, as always, if any of these assumptions on my part are in error, I would love to be corrected by more knowledgeable members of the community.)
You have to make sure, that the background process is not terminated when the processing of the page finished. If you are on a Linux system, you could try to use the nohup command:
$command = 'nohup php somefile.php';
pclose(popen($command,'r'));
If it still gets terminated, you could try the "daemon" command.
I am trying to run a php script on my remote Virtual Private Server through the command line. The process I follow is:
Log into the server using PuTTY
On the command line prompt, type> php myScript.php
The script runs just fine. BUT THE PROBLEM is that the script stops running as soon as I close the PuTTY console window.
I need the script to keep on running endlessly. How can I do that? I am running Debian on the server.
Thanks in advance.
I believe that Ben has the correct answer, namely use the nohup command. nohup stands for nohangup and means that your program should ignore a hangup signal, generated when you're putty session is disconnected either by you logging out or because you have been timed out.
You need to be aware that the output of your command will be appended to a file in the current directory named nohup.out (or $HOME/nohup.out if permissions prevent you from creating nohup.out in the current directory). If your program generates a lot of output then this file can get very large, alternatively you can use shell redirection to redirect the output of the script to another file.
nohup php myscript.php >myscript.output 2>&1 &
This command will run your script and send all output (both standard and error) to the file myscript.output which will be created anew each time you run the program.
The final & causes the script to run in the background so you can do other things whilst it is running or logout.
An easy way is to run it though nohup:
nohup php myScript.php &
If you run the php command in a screen, detach the screen, then it won't terminate when you close your console.
Screen is a terminal multiplexer that allows you to manage many processes through one physical terminal. Each process gets its own virtual window, and you can bounce between virtual windows interacting with each process. The processes managed by screen continue to run when their window is not active.