PHP exec and shell_exec: no output - php

Yesterday I asked this question
Building g++ via PHP: no build output
That part is solved, but now I now have a similar/related problem.
When I run the compiled executable (see other question) via my browser address bar, the output is printed to the browser window as expected.
However ,I want to use it within PHP and get the output via the return of the exec or shell_exec functions. I have tried various things, including the following:
$output = "test.cgi";
echo shell_exec($output);
echo shell_exec("$output 2>&1");
echo system($output);
Nothing works..
Internally, the executable is c code, compiled by g++, and is using print_f. That should output to STDOUT by default accoding to the specs, so I do not understand why this isn't working.
Can anyone help?

For anyone with the same problem, I found the solution:
exec needed an absolute path to the file

Related

Using PHP to call Virtualenv’ed Python Script

Last night I spent 5.5 hours trying make PHP execute and receive the output of Virtualenv’ed Python script. Nothing worked; except for scripts that were not Virtualenv’ed.
What I am trying to do:
I am trying to make PHP call a virtualenv’d install of the Newspaper lib output text when I call it.
What I have now:
PHP: (updated)
<?php
$output = exec('newspaper2/bin/python3 /var/www/html/components/python/test.py 2>&1', $output2);
print_r(error_get_last());
echo $output2;
echo $output;
…this works when using a non-virtualenv script
Python: (updated)
from newspaper import Article
url = 'http://example.com/'
article = Article(url)
article.download()
article.html
article.parse()
article.authors
article.publish_date
string = article.text
print(string)
What the issue is:
I can run the script that PHP is running from the command line and it outputs just fine.
What I have tried:
With PHP, (I have tried all the “exec” calls for PHP) it cannot seem to open the virtual environment and returns nothing.
Before the script I have called “python3” and a few other things to no avail.
Yes, I have chmoded it to be executable…
I feel like this should be so simple.
I have tried suggestions on other posts and all over the web to no avail.
Questions:
Did I set up the virtualenv wrong?
At the top of the Python script, instead of the “#!/usr/bin/env python3” should I call something else?
If so, where do I find it? Should I start from scratch and will that
help?
Thank you for your help;
PS: I am running Ubuntu16, PHP7 and I need to use Python3
In the virtualenv'ed scripts (i.e. installed via the setuptools' entry-points), you should not touch the shebang (#!... first line). It is populated by the virtualenv & setuptools & related tools.
If you specify your own shebang, then it is not virtualenv'ed script. In that case, call python directly:
exec('/path/to/venv/bin/python3 /var/www/html/components/python/testing.py');
Alternatively, you can put the absolute path to the virtualenv's python binary to the py-script, but this does not look a good idea.
Also, remember that virtualenvs are non-relocatable. So they should stay in the path where they were created.
Also note that exec() returns only the last line of the output. You probably want shell_exec() or exec('...', $output) to get the whole output.
Also, it is unclear what happens with your script, and what is being printed on stderr. Try this command to see what is the error:
exec('/path/to/script 2>&1', $output)
#OR:
exec('/path/to/venv/bin/python3 /path/to/script 2>&1', $output)
OK, I finally figured it out and learned a lot in the process. The newspaper lib that I am using by default tries to write to the base of the users home directory. In this case, it was attempting to write to www-data, /var/www.
To fix this:
Go to the settings.py file in the newspaper library.
Edit the variable DATA_DIRECTORY = '.newspaper_scraper' and change it to DATA_DIRECTORY = '.path/to/writable/directory'
Save the file and you should be good to go.
I have no idea why it was not returning the errors that would have explained this sooner.
Hope this helps anyone else.
Thank you so much Sergey Vasilyev for your help. I appreciate it greatly.

Execute a php script within a running php script

I'm trying to execute a php script from a php file, but it seems that i can't get the correct bin path of the php.exe. Its not doing anything as far as i can tell. Lets assume service-oauth.php is a simple echo.
EDIT3:
I fixed it using php-cli instead of php or the php bin path, i must admit that i tried this before but it seems something else was off when i tried this (one of the first things i tried). The answer provided by Keith in Can't execute PHP script using PHP exec , so it ended being a duplicate :S, thanks for the help to those who commented.
EDIT2:
I tried calling the script directly from the server console as #Dagon suggested and it works, both using the php env variable and the php path to the bin, its clear that the path is correct, but something is preveting to get the output or to run the script using the php exec() function
service-oauth.php
<?php echo "Hello there"; ?>
And this is my script:
$basePath = plugin_dir_path( __FILE__ ); # Wordpress function, asume it works.
$fileToExc = $basePath . 'service-oauth.php';
# PHP_BINDIR: /usr/local/bin
# PHP_BINARY: /usr/bin/php
# exec("which php") /usr/bin/php
$phpPath = exec("which php");
$output = exec("$phpPath $fileToExc");
print_r($output);
There are a lot of answers on stackoverflow that recommend any of those 3 options i commenented in the code, but none of them seems to work, not sure if it is the path or something else that is not working. I've tested this script on my localmachine (windows) and it works (even though i had to use a hardcoded path to the bin since i wans't getting the correct path), but i'm testing on my production server (linux) and is not working.
Note: Let me be clear, that this is not a duplicate, i've tried the following answers in these posts and many others, and it didn't work for me:
How to get path of the php binary on server where it is located
Can't execute PHP script using PHP exec
PHP exec to run a file
How to call shell script from another shell script?
Execute a PHP script from another PHP script
I've also tried using .exe at the end of the binary(windows localmachine), using php-cli instead of php, and i've tested the excec function and it works, but not in this case. Also tried with a shebang in the called script.
It's propably something simple that i'm not aware of but i've been spending a lot of hours searching and testing and nothing so far. Any help is appreciated.
EDIT:
Using scandir on the bin folder shows
scandir("/usr/bin/")
Array(
...
[632] => php
[633] => php-cgi
[634] => php-cli
...
)
Tested if in safe mode using ini_get('safe_mode'), but it seems off.
I fixed it using php-cli instead of php or the php bin path, i must admit that i tried this before but it seems something else was off when i tried this (one of the first things i tried). The answer provided by Keith in Can't execute PHP script using PHP exec , so it ended being a duplicate :S, thanks for the help to those who commented. – Zagen

php exec() is not executing the command

I have tried to use exec() with 'whoami' to check if it works and I got the result of
nt authority\system
Now I need to run a .exe file with parameters from php via exec() function.
I tried this in command prompt and it actually runs the program with given parameters. This is the example command.
NOTE the exe file gets 3 inputs (folder, file_name, report_file_nmae)
> ..\..\some_file.exe folder="C:\path_to_folder" param=1.xml report=2.xml
But when I run this command from php file:
exec('..\..\some_file.exe folder="C:\path_to_folder" param=1.xml report=2.xml');
nothing is happening. This is the first time I am using exec() function, so I am not familiar with its details. What is wrong?
I tried using:
\\ instead of \
escapeshellarg() on the directory
added "" around directory folder names
No luck
Addendum:
echo exec($command) // echos < .... why?
or
exec($command, $output);
print_r($output); // Array()
I even changed the permission on the file to full control to all users.
If I call the program from command prompt, I can see the icon appearing next to clock for a second.
But the same call from php will not even call the program.
Edit
Even exec('notepad.exe'); is not working. Something has to be done with php configurations maybe?
I already said that I was new to exec() function. After doing some more digging, I came upon 2>&1 which needs to be added at the end of command in exec().
Thanks #mattosmat for pointing it out in the comments too. I did not try this at once because you said it is a Linux command, I am on Windows.
So, what I have discovered, the command is actually executing in the back-end. That is why I could not see it actually running, which I was expecting to happen.
For all of you, who had similar problem, my advise is to use that command. It will point out all the errors and also tell you info/details about execution.
exec('some_command 2>&1', $output);
print_r($output); // to see the response to your command
Thanks for all the help guys, I appreciate it ;)
You might also try giving the full path to the binary you're trying to run. That solved my problem when trying to use ImageMagick.

How to print the output of a shell command in php?

I want to print the output of a command named jnettop into an html file.
I am very familiar with shell_exec() and sort.
But it doesnt work as the command that Im using doesnt have a bash mode like top that is described here.
The end goal is have a site that I go to and I see the information that jnettop would normally display in terminal.
Here is the link to jnettops wiki page.
You might try passthru() or exec() with the output argument peresent.
the command that Im using doesnt have a bash mode like top
Sure it has: jnettop --display text.

Problems when trying to exectue exec("unix2dos xxx") in PHP/Apache

In a previous post, I was trying to update the encoding for a download file from php. One of the suggestions was to run the unix2dos command before sending the file to the user. This works great when I run the command on the linux box, but when I try and run the command from php I get nothing. Here is what I tried:
$cmd = "unix2dos -n $fullPath $downloadFile";
echo exec($cmd, $out, $retVal);
This displays nothing to the screen, $retVal is 0, and $out is an empty string.
echo system($cmd, $retVal);
This displays nothing to the screen, $retVal is 0.
echo shell_exec($cmd);
This displays nothing to the screen.
I have also tried escaping the command and it parameters like:
$cmd = escapeshellcmd($cmd);
and
$cmd = "unix2dos ". escapeshellarg("-n \"$fullPath\" \"$downloadFile\"");
Please let me know if you see something that I am doing wrong.
Thanks!
Edit: Here is some info that may be helpful.
unix2dos version: 2.2 (1995.03.31)
php version 5.2.9
Running in apache 2 on in Redhat Enterprise Linux 4
Have you considered a pure PHP solution?
<?php
$unixfile = file_get_content('/location/of/file/');
$dosfile= str_replace("\n", "\r\n", $unixfile );
file_put_contents('/location/of/file/', $dosfile);
?>
Something like that should do it, although untested :)
Shadi
See which user the PHP exec command is running as:
<?php system('whoami'); ?>
If this command fails then you likely do not have permission to use exec() or system(), so check your INI files. But be sure to check the correct ones! On Debian systems there are separate Apache and CLI INI files stored at /etc/php5/apache/php.ini and /etc/php5/cli/php.ini respectively. Sorry I do not know the locations for RedHat.
If the whoami command succeeds, make sure that the unix2dos command can be run by the user that is shown, and that the same user is allowed to make changes to the files in question by using chmod or chown.
Are you using the full path to unix2dos? Perhaps the executable is in your path for your shell but not in the path that PHP is using.
My implementation of unix2dos produces no output. If the return value is 0 then the command succeeded and your file has been updated.
The only other thing I see is the -n option which my version doesn't seem to have. You should probably check your man page to see what options it supports
unix2dos does not display the file it converts. Therefor you must display it yourself. A very basic way to do it could be :
$cmd = "unix2dos -n $fullPath $downloadFile";
echo exec($cmd, $out, $retVal);
include "$fullPath."/".$downloadFile;
Using include is pretty dirty but quick and easy. A cleaner way would be to use fopen and read the file then display it.
You'd better create a function that enclose all the operation : conversion + display so you'll have everything at hands.
But, If I were you, I'd prefer to not use exec at all and use FileIterator with a trim on every line so you will not have to care about the carriage return nor deal with a hazardous shell binding.
Not sure about your exact problem, but debugging suggestion:
Try first setting $cmd to ls. See if that works. Then try using /bin/ls (use the full path.)
If those don't work, then there might be a problem with your PHP configuration - there might be a safemode parameter or something which disallows the use of exec(), shell_exec(), or system() functions.
I got the source code from here.
http://www.sfr-fresh.com/linux/misc/unix2dos-2.2.src.tar.gz
I compiled it and then ran the tool. This was my output:
rascher#danish:~/unix2dos$ ./a.out -n 1.txt 2.txt
unix2dos: converting file 1.txt to file 2.txt in DOS format ...
I think the problem is this: the program writes all of its output to stderr, rather than stdout. If you look at the source code, you can see "fprintf(stderr, ...)"
As far as I know, PHP will only read the part of your program's output that is sent to STDOUT. So to overcome this, it seems like you have to redirect the output of your program (unix2dos uses stderr) to stdout. To do this, try something like:
$cmd = "unix2dos -n $fullPath $downloadFile 2>&1"
The "2>" means "redirect stderr" and "&1" means "to stdout".
In either case, I would imagine that the file was converting properly, but since you weren't getting any of the expected output, you thought it was failing. Before making the change, check on the output file to see if it is in DOS or UNIX format.

Categories