I have a shell script which is running in background and i want to know the shell script execution completion and send it to the PHP which is running in browser currently.PHP and shell script has no link now.How to get the shell script completion and signal it to the PHP
I understand this is more a conceptual question. Two simplest methods that come into mind are:
1) Use a "flag file" that you create from the shell script. When the file exists, it means the script is done. When there's no file, the script still runs. Or other way around. That's common method for shell scripts anyway.
For more background info on how to create this from your shell script, see http://www.cyberciti.biz/tips/shell-scripting-bash-how-to-create-empty-temporary-file-quickly.html
From your PHP code, you test for the (non)existence of that file. PHP has a lot of functions for that, eq. look into file_exists ( string $filename ), see http://php.net/manual/en/function.file-exists.php
2) From the shell script, use a URL parameter when you call the php script and from your PHP code, you read the parameter and work with that. PHP has a lot of functions for that (eg. look into $_SERVER['QUERY_STRING']). Some more on using the $_SERVER vars, see http://php.net/manual/en/reserved.variables.server.php
Hope this helps...
Here you got everything you need, examples, explanations and more.
http://php.net/manual/en/function.shell-exec.php
Related
I have a scraper which scrape one site (Written in python). While scraping the site, that print lines which are about to write in CSV. Scraper has been written in Python and now I want to execute it via PHP code. My question is
how can I print each line which is getting printed by python code.
I have used exec function but it is none of my use and gives output after executing all the program. So;
Is it possible to get python output printed while it is getting executed via PHP.
If i understand it well, your python scraper output to a file and you want to "live" display the output via php. What about doing and loop in php in which you use filemtime to know whether or not the file has been updated? You might add a little sleep in order not to overload your server.
If your are using a web page, you may use AJAX to reload only the concerned part of the page at a regular interval.
Hoping this helps you.
Simple case
Assuming execution of scraper is limited to php runtime, run it via popen: http://php.net/manual/en/function.popen.php
More involved case
If you want scraper to run on background and only connect to it vis php from time to time, you can either use some pub/sub toolkit or implement a small web server in the scraper that you can fetch result updates with fopen("https://localhost:port/...") or curl. Many other rpc mechanisms are possible, domain sockets, watching a file, sysv rpc...
I'd communicate using stdout instead of a file. Meaning the python script writes to stdout and the php script reads that.
Using proc_open you can control the python process from php and also read it's output.
Instead of using exec you could use passthru, that will output the data directly to the browser. http://php.net/manual/en/function.passthru.php
That should be enough to get the println from your script.
I think I have a fair idea of what you are saying put I am not too sure what you mean.
If you mean to say that everytime the python script does a print, you want the php code to output what was print?
If that is the case you could pass it as a POST DATA via HTTP. That is instead of printing in Python, you could send it to the PHP Script, which on receiving the data would print it.
I am not too sure if this is what you want though.
For proper communication you need to setup any medium, so you can use fifo, through it you can write string in python and read it with php.
For PHP fifo
http://php.net/manual/en/function.posix-mkfifo.php
For Python
http://www.doughellmann.com/PyMOTW/Queue/
Simply use system() instead of exec(). exec() saves all lines of stdout output of the external program into an array, but system() flushes stdout output "as it happens".
is it possible to launch a php script in background on the webserver with js and let it run even if you change page or not visit the site at all and then get the current status if you call the php script in a second moment?
This php script will process data for hours and sleep for X seconds/minutes for each loops. If what I asked before is possible how can I even get "echos" from it if php will only generated an output only when the script ends?
Maybe this is not a job for PHP?
thank you
EDIT: on a windows machine with apache
It certainly is possible - I have several scripts that run 24/7 written in PHP. Check out Creating Daemons in PHP. It has good info on how to 'daemonize' a php script so that it will run like a service, and it also covers signal handling.
To get debugging output you would redirect to a log file. Do a search on "unix redirect output" as there is a lot of info available.
In Windows it's not much different from UNIX.
First of all, you need to create a PHP script with a run loop. For example, take a look at this: http://code.google.com/p/php-apns/ . This is a PHP "daemon": the main script, PushMonitor.php, runs forever, because it has an infinite loop. It polls a queue at regular intervals, then execute the actions and then wait. Really simple, actually!
The problem, in your case, is that you want to launch the "daemon" from a PHP script.
You may want to look at this: http://robert.accettura.com/blog/2006/09/14/asynchronous-processing-with-php/ (first example code) . You will execute something like launchBackgroundProcess('php myscript.php') .
Note that on the code there's the "start /b" command (and the "&" at the end of the command for UNIX). That is important, because otherwise your process would be killed when the PHP script of the web page is terminated (children process die after parent dies!).
Also, remember that the "php" executable (cli) must be in your path (so you can execute "php" from the command line).
Since the PHP script of the page launching the background process is going to terminate, you can't directly catch the "echoes" in a simple way. My suggestion is to write all output to a file (or a database etc), and then read the contents from that source when necessary.
So, instead of "echo", you will use file_put_contents() etc.
I have PHP script, which is requested by user. In this script I want to run C++ script(exe), but not wait until this script finishes(because this script does some post-process with data, which PHP doesn't care about). Is there anyway to do this on Apache?
You want the php exec function. Bear in mind the comment on the page about apache:
When calling exec() from within an
apache php script, make sure to take
care of stdout, stderr and stdin (as
in the example below).
I have a web service endpoint that needs to invoke another developer's CLI PHP script as part of its run. Pseudocode like so:
function startCLI($input, $output){
$cmd = escapeshellarg('php bin/startcli.php $input $output');
exec($cmd, $output, $ret);
if ($output){
print_r($output[0]);
}
}
Now, you might be asking: why not pass the $_POST['var'] to the clistart.php script?
Well, you get what you pay for when you get your legacy code from overseas, sometimes, and the time it would take me to take apart their system and put it back together is greater than the time I have to implement the whole solution.
So let's just stipulate that I cannot add new variables to the clistart.php script, and take it from there. Hell, take it as an academic exercise. Does a CLI script executed from a web-requested PHP script have access to $_GET or $_POST for its run?
UPDATE: I've tried both adding keys to $_ENV and getenv() and putenv(), but the result is the same - I can update the environment for the current script and the child script that it's executing to QUEUE the job, but since the jobs are then being run by a persistent process that has its own $_ENV context, there doesn't appear to be a way to pass that variable along to the persistent process' context.
I'll either have to resort to the database or a file touch, unless someone has another idea.
$_GET and $_POST are part of the scripts web request context and won't be available in CLI, it will have it's own context populated.
Not without exporting the array contents as environment variables - via putenv.
But why is a CLI script looking into HTTP variables anyway? A CLI-only script wouldn't even look at them.
Or by CLI do you mean it's designed to run as a CGI script?
How can I run several PHP scripts from within another PHP script, like a batch file? I don't think include will work, if I understand what include is doing; because each of the files I'm running will redeclare some of the same functions, etc. What I want is to execute each new PHP script like it's in a clean, fresh stack, with no knowledge of the variables, functions, etc. that came before it.
Update: I should have mentioned that the script is running on Windows, but not on a web server.
You could use the exec() function to invoke each script as an external command.
For example, your script could do:
<?php
exec('php -q script1.php');
exec('php -q script2.php');
?>
Exec has some security issues surrounding it, but it sounds like it might work for you.
// use exec http://www.php.net/manual/en/function.exec.php
<?php
exec('/usr/local/bin/php somefile1.php');
exec('/usr/local/bin/php somefile2.php');
?>
In the old days I've done something like create a frameset containing a link to each file. Call the frameset, and you're calling all the scripts. You could do the same with iframes or with ajax these days.
exec() is a fine function to use, but you will have to wait until termination of the process to keep going with the parent script. If you're doing a batch of processes where each process takes a bit of time, I would suggest using popen().
The variable you get creates a pointer to a pipe which allows you to go through a handful of processes at a time, storing them in an array, and then accessing them all with serial speed after they're all finished (much more concurrently) using steam_get_contents().
This is especially useful if you're making API calls or running scripts which may not be memory-intensive or computationally intensive but do require a significant wait for each to complete.
If you need any return results from those scripts, you can use the system function.
$result = system('php myscript.php');
$otherresult = system('php myotherscript.php');