Running Python Code from PHP - php

I have a Python file which uses
raw_input()
to enter in a URL. I then scrape the website using BeautifulSoup and ask the user a few other questions based on thee data on the website (that I just scraped..)
I wish to convert this command-line tool into a web app.
How would I go about doing this?
shell_exec()
won't do what I want, because (as far as I know) can't input data from raw_input() through PHP..

You are looking for readline or stdin stream:
With php://stdin
$fp = fopen("php://stdin","r");
$line = rtrim(fgets($fp, 1024);
With readline:
$line = readline("Command: ");

I actually created a dnsTools script that would run a perl script similar to how it sounds like what you want to do. I used shell_exec here is an example of what I did
$ip=shell_exec('/usr/bin/perl ./dnstools.pl -ta -h'.$_POST["domain"].' -s#vnsc-lc.sys.gtei.net');
Then my script would just return the IP as a string.
Remember:
The output from the executed command or NULL if an error occurred or the command produces no output.
http://php.net/manual/en/function.shell-exec.php
Also, keep in mind the security issues using the command could pose if there is user input.
If shell_exec is turned off you could try using curl to run the command though the web and then still process the results.

Related

PHP runs Perl script from command line successfully but I get no output displayed

I have a problem displaying the results of a Perl script that I am calling from my PHP webpage. The Perl script constantly monitors a socket and will display the output of this when run from the command line and also saves the output to a file. I know the Perl script is being called and running successfully as the text file is being updated but I do not get the output on the webpage as I was hoping for.
I have tried using the system(), exec(), passthru() and they all allow the Perl script to run but still with no output on the webpage so I am obviously missing something. Am I using the correct functions? Is there a parameter that I need to add to one of the above to push the output back to the webpage that calls the Perl script?
One example of what I have tried from the PHP manual pages:
<?php
exec('perl sql.pl', $output, $retval);
echo "Returned with status $retval and output:\n";
print_r($output);
?>
Edited to include output example as text instead of image as requested.
# perl sql.pl
Connecting to the PBX 192.168.99.200 on port 1752
04/07 10:04:50 4788 4788 3256739 T912 200 2004788 A2003827 A
I'm no PHP expert, but I guess that exec waits for the external program to finish executing before populating the $output and $return variables and returning.
You say that your sql.pl program "constantly monitors a socket". That sounds like it doesn't actually exit until the user closes it (perhaps with a Ctrl-C or a Ctrl-Z). So, presumably, your PHP code sits there waiting for your Perl program to exit - but it never does.
So I think there are a few approaches I'd investigate.
Does sql.pl have a command-line option that tells it to run once and then quit?
Does PHP have a way to send a Ctrl-C or Ctrl-Z to sql.pl a second or so after you've started it?
Does PHP have a way to deal with external programs that never end? Can you open a pipe to the external process and read output from it a line at a time?

Running a python code with php

I have a python script which is needed to be run by php:
<?php
$command = escapeshellcmd('/home/Desktop/test.py');
$output = shell_exec($command);
echo $output;
?>
The out put of the python script is a binary file but I get the following error in the log:
Unable to access the X Display, is $DISPLAY set properly?
The php code works fine from the terminal but no luck when I try to run it from the browser. Any idea what is going on? Ideally, I don't want to change my program. I want to know how you can rectify the X Display error. Is there a way to check if $DISPLAY is set properly? ( I am working with Ubuntu)
I tried this : pidof X && echo "yup X server is running" on my terminal and it is saying yup x server is running!
Add the following text as the first line of your Python script:
#!/usr/bin/python
Without this, the kernel doesn't know what interpreter to run your script with, and may end up trying to launch it using /usr/bin/import (because that word probably appears on the first line of the script). The import utility requires access to the X11 display (it's a screenshot utility, basically), which is why you're getting this error.
The python file you need may need to open a window to run. You say you saw it run in terminal though? What's test.py? Is it propitiatory?
If you try using this as a command in your PHP: (not 100% that the shell escape won't strip this so may need to comment that out)
python -c \'print \"Test\"\'
and see if you get the output text back. If so it's a python issue not PHP and the test.py file may be instantiating something that needs the $DISPLAY var set. PHP doesn't set the $DISPLAY var as it is shell commands not GUI.
try popen
$command = "/usr/bin/python /home/Desktop/test.py";
$handle = popen($command, "r");
"r" for read
$read = fread($handle, 10);
10 is the size of output you want to take,
echo $read ;
hope it helps,

PHP running external program, Apache hangs

Basically my situation is as follows.
Upload file
Run external process on file (which generates another file)
When external process is down, process the generated file.
Currently in PHP I run the program as follows:
$cmd = 'cd the_directory/; ./the_program'
system($cmd);
The program runs fine and everything, but the program at the end says "Press Enter to exit..." And thus Apache is hanging indefinitely as this program is waiting for user input. Our partner declares that they have this program integrated into their backend flawlessly and does not experience this issue. Up until now all external programs that i have executed in PHP exit without requiring user input which seems to be the norm for this situation.
It seems to me that the code should just simply not have the end message requiring user input. Am I missing something? Or is there a way to get around this? Or do they just need to change their code?
Thanks!
I think you should try proc_open.
With it you can not only execute an external command as a process, but also set pipes to get and send information to that process.
Take a close look to the third parameter of this function, and study the example in the PHP manual for this function, where you can see something like this:
fwrite($pipes[0], '<?php print_r($_ENV); ?>');
so, you can write what you need to the input pipe of the process you've just opened.
if you use Windows environment:
$run_cmd = "cmd /c c:/app_folder/app.exe";
$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run($run_cmd, 0, false);
Note that the latter will cause the process window to close on end
If you use UNIX (haven't tested it myself yet):
exec('\app_folder\app &');

Problem using PHP exec command to execute a batch file

I'm attempting to get PHP to call a batch file which will take an RTF file and convert it to a PDF using an OpenOffice macro. I've tested the batch file on the command line and it works fine, but I'm not having any luck calling and using the same batch file from PHP.
My machine OS is XP professional SP 3. I'm running IIS 6 and PHP version 5.2.9.
I've granted execute permissions to the internet user on c:\windows\system32\cmd.exe.
I specified the full path to the batch file being executed and the full path to the RTF file to be converted.
The PHP looks like this where $arg is the RTF to be converted:
$arg = "C:\\web_root\\whatever\\tempOutput.rtf";
$command = "c:\\windows\\system32\\cmd.exe /c c:\\web_root\\whatever\\convert.bat $arg";
Then inside a try-catch I call the exec command:
exec("$command 2>&1 && exit", $ret, $err);
I echo the results after the catch:
echo "ret: ";
print_r ($ret);
print "<br>";
echo "err is ";
echo $err;
print "<br>";
echo "DONE!";
And this is what I see:
ret: Array ( )
err is 0
DONE!
The RTF file does not get converted and I'm not seeing the errors. Any ideas on what I can try next? Thanks!!!
I'm going to bet this is about permissions.
In a typical setup, PHP runs as apache - so you'll want to make sure apache has the rights to execute the batch file.
also, check this relevant SO question, and this google search.
Looks like the output array is empty. Is your batch script supposed to have output?
Also, escapeshellcmd and escapeshellarg should be used
Are you using IIS as your webserver? If so, the PHP exec function will not work by default and you should NOT circumvent the security measures that prevent it from running.
Check your event viewer and you should find some errors pertaining to your problem. Run a query through google for: IIS PHP exec. This should give you a large selection of information about the problem.
Basically, the PHP exec function tries to fork a new cmd.exe instance. IIS prohibits this because it could open a security hole in the system.
The best solution that I have come up with is to have your php script either write the command that you want to execute to a flat file or make a database entry. You will then need to write a seperate script that is launched by the windows scheduler to run every 10 minutes or so that will check your flat file or database for commands to run. The new script will then run the commands and then place either the results or an execution confirmation that your web app will be able to access at a later time.
It's a kludge for sure.
Is PHP running in safe-mode? If so, shell commands are escaped with escapeshellcmd. Perhaps this is the problem?
Do you have control of the server running the PHP script?

How do I escape a PHP script to an external editor and return afterwards?

Specifically I have a PHP command-line script that at a certain point requires input from the user. I would like to be able to execute an external editor (such as vi), and wait for the editor to finish execution before resuming the script.
My basic idea was to use a temporary file to do the editing in, and to retrieve the contents of the file afterwards. Something along the lines of:
$filename = '/tmp/script_' . time() . '.tmp';
get_user_input ($filename);
$input = file_get_contents ($filename);
unlink ($filename);
I suspect that this isn't possible from a PHP command-line script, however I'm hoping that there's some sort of shell scripting trick that can be employed to achieve the same effect.
Suggestions for how this can be achieved in other scripting languages are also more than welcome.
You can redirect the editor's output to the terminal:
system("vim > `tty`");
I just tried this and it works fine in windows, so you can probably replicate with vi or whatever app you want on Linux.
The key is that exec() hangs the php process while notepad (in this case) is running.
<?php
exec('notepad c:\test');
echo file_get_contents('c:\test');
?>
$ php -r test.php
Edit: As your attempt shows and bstark pointed out, my notepad test fires up a new window so all is fine, but any editor that runs in console mode fails because it has no terminal to attach to.
That being said, I tried on a Linux box with exec('nano test'); echo file_get_contents('test'); and it doesn't fail as badly as vi, it just runs without displaying anything. I could type some stuff, press "ctrl-X, y" to close and save the file, and then the php script continued and displayed what I had written. Anyway.. I found the proper solution, so new answer coming in.
I don't know if it's at all possible to connect vi to the terminal php is running on, but the quick and easy solution is not to use a screen editor on the same terminal.
You can either use a line editor such as ed (you probably don't want that) or open a new window, like system("xterm -e vi") (replace xterm with the name of your terminal app).
Edited to add: In perl, system("vi") just works, because perl doesn't do the kind of fancy pipelining/buffering php does.
So it seems your idea of writing a file lead us to try crazy things while there is an easy solution :)
<?php
$out = fopen('php://stdout', 'w+');
$in = fopen('php://stdin', 'r+');
fwrite($out, "foo?\n");
$var = fread($in, 1024);
echo strtoupper($var);
The fread() call will hang the php process until it receives something (1024 bytes or end of line I think), producing this :
$ php test.php
foo?
bar <= my input
BAR
system('vi');
http://www.php.net/system

Categories