PHP exec output differs from Command line output? - php

Context:
I have a simple html frontend that allows the user to enter some basic detail, e.g. colours to use. This then gets placed in my strings.xml file so that we can quickly push out preview versions. Windows 10 64bit running WAMP, building with Gradle 3.6.
The Goal:
To build the updated app from command line with PHP.
The issue:
The project builds correctly when I manually build via the command line, but the build fails when I use PHP's exec function.
The gradle wrapper has to be executed from the base project folder, thus the need for cd...
Firstly I clean the project, so I do:cd path/to/projectdir && gradlew clean 2>&1
Which work as expected from exec and command line.
Next is to build with cd path/to/projectdir && gradlew assemble 2>&1.
Running the above via command line returns success:
However, running the same with exec('cd path/to/projectdir && gradlew assemble 2>&1', $output) and printing output returns:
...[24] => FAILURE: Build failed with an exception.
[25] =>
[26] => * What went wrong:
[27] => Execution failed for task ':app:processDebugResources'.... (full output https://pastebin.com/zdeXuukp)
As far as I can tell, the only difference between the two, is the process owner (based on exec('whoami')).
Any idea if this might be the cause for it failing or what else might be causing the PHP exec build to fail?

After much digging, my suspicions were confirmed, it was indeed due to the apache user having incorrect permissions.
This is the answer: Is it possible to have WAMP run httpd.exe as user [myself] instead of local SYSTEM?
In this instance, I was just playing around on my local machine and would obviously not recommend this approach in a production environment, anyway, here's how I solved it:
Close WAMP.
Open services.msc (win+r services.msc)
Change wampapache64, wampmariadb64 & wampmysqld64 Right click>Properties > Logon Tab and specify a User account to start the service as (I used my user account, as I knew it already has the correct permissions) and Apply changes.
Open WAMP.
Accessing a PHP page through the browser with a simple echo exec('whoami') should now output the same as running whoami directly in the command line.
My script is now executing correctly and returning the same output as when run through the command line.

Related

php exec SVN empty output, works fine in terminal under same user

I have an issue updating SVN from within PHP. It was working fine then suddenly stopped working a few days ago.
I am running PHP-FPM 5.5 through Nginx. SVN version is 1.8.8.
The code:
exec("svn cleanup $path");
exec("svn revert $path -R");
exec("svn update $path --accept theirs-full --non-interactive", $output, $return);
echo "Return: $return\nOutput: ".print_r($output, true)
Output:
Return: 1
Output: Array
(
)
When I run this in terminal (under the same user as PHP-FPM and Nginx), I get the expected output:
Updating '/path/to/app':
At revision 100
PHP CLI also works with the correct output (under same user as PHP-FPM and Nginx):
php5 /path/to/app/svnupdate.php
Based on this it seems to be specifically an issue with PHP5-FPM exec on svn. But how can I debug this and figure out what is wrong?
Thanks.
Updates from comments to keep everything together:
Tried the proc_open approach, running only "svn cleanup $path" via that failed and caused all files to lock. running same command under same user in terminal worked fine and unlocked all files again.
Tried full path to svn bin, no difference
Running "svn info $path" seems to work fine, no files were locked.
The following commands all fail in php exec/proc_open (without any error message or output) and lock the app files:
svn cleanup $path
svn revert $path -R
"svn update $path" returns "Updating '$path'" but stops there, previously the current build number would be returned on a second line.
I have a 2nd setup with a different app and svn server but running the same version OS and all software, this one is working fine. I think that rules out software.
i tried rolling the issue server back to a version from 2 months ago when it was working, the server automatically updates software and app on launch but should not have touched config files or cache. After it was available it was still showing the same issue. Fairly sure that rules out software config files/cache.
Which leaves only app codebase and svn server as a possible cause. I'll try resetting the svn server next and redoing the svn project.
Update 2:
Recreated the project on the SVN server, remove application from app server and all svn config directories, checked out the new project from SVN server (build 1). Still the same error. !_!
Update 3:
After doing all of the above i concluded that left only the file base that could be causing the issue. And it was, there was a "Can't convert string from native encoding to 'UTF-8':" error being thrown by SVN because of a few files with special characters in the filename. Interestingly the error only stopped the process when running from php-fpm and not in terminal. NO IDEA WHY. I added export LC_CTYPE=en_US.UTF-8; to the exec command and now it is working fine.
exec("export LC_CTYPE=en_US.UTF-8; svn update $path",$output);
The exit status (1) indicates that the command fails for some reason. To find out the reason, you need to capture the standard error with the help of proc_open function as shown in this answer. The exec function captures only the standard output.
There was a "Can't convert string from native encoding to 'UTF-8':" error being thrown by SVN because of a few files with special characters in the filename. Interestingly the error only stopped the process when running from php-fpm and not in terminal. NO IDEA WHY. I added export LC_CTYPE=en_US.UTF-8; to the exec command and now it is working fine.
exec("export LC_CTYPE=en_US.UTF-8; svn update $path",$output);
I used this code to actually discover the error in php:
$proc = proc_open('svn update', $desc, $pipes);
echo 'PIPE 1: '.stream_get_contents($pipes[1]); fclose($pipes[1]);
echo 'PIPE 2: '.stream_get_contents($pipes[2]); fclose($pipes[1]);
echo 'STATUS: '.proc_close($proc);
In my situation, I fixed the problem by following steps:
check which user php-fpm runs, in my case, it is nginx
cat /etc/passwd to check 'nginx' user, its home directory is '/var/cache/nginx'
cp /root/.subversion to /var/cache/nginx
reconfig /var/cache/nginx/.subversion/servers if you need
then is works well
Maybe the debug process is helpful:
I guess it is because of the permission problem
I change nginx from /sbin/nologin to /bin/bash
I run runuser -l nginx -c 'php myphpscript_which_exec_svn_command.php'
It will output some information you need
So I get the solution, for security reason, change nginx user property back(/bin/bash to /sbin/nologin)

Git pull “permission denied” when using shell_exec in PHP

I'm trying to make a hook on bitbucket, that executes a php file, and this file executes the pull command:
shell_exec('/usr/local/cpanel/3rdparty/bin/git pull');
The pull command works fine on the SSH console, but the PHP returns the error:
Permission denied (publickey). fatal: Could not read from remote
repository.
Please make sure you have the correct access rights and the repository
exists.
The command --version shows the path to git is right, whoiami returns the same user on both, so I don't know if it is a permission issue.
What can be going wrong?
Edit: An additional issue: the alias I added for git don't work on PHP, only the full path as above. Via terminal it works just fine. Maybe it's the same reason why the key don't work in php.
Edit 2: $PATH is different on both.
When you run this command within a PHP script you are not running the command as yourself:
shell_exec('/usr/local/cpanel/3rdparty/bin/git pull');
The reason it works from the terminal console is you run the command as yourself from the console. But on a web server, you are not the user running the command. Remember: When you run PHP on a web server, it is a an Apache module. Meaning the web server user—which could be www-data, root or even apache on some systems—is running the PHP script which then runs the shell_exec command.
So it would never work as you have it setup. Perhaps you can kludge something together that would allow a key-pair to be used by the web server for these purposes, but that seems like a security risk waiting to happen.

Running Linux Command from PHP

I have a bit of a unique situation. I'm trying to run a video encoding program from a PHP script called Diascope, which relies on the 'convert' command provided by ImageMagick. I have a bash script that executes a really simple conversion and then it runs the application called Diascope. This is the conversion code, and the following does work, it creates the new file
convert image.jpg image.png
Shows no errors, but then I run Diascope like this
diascope -clean audio.txt
And I can see that Diascope loads property because it prints "Diascope 0.2.1":
diascope 0.2.1 (ms 2006-2010) slideshow generator See
http://diascope.sf.net for documentation and updates.
Error: executable program not found: convert Please see the
requirements for diascope in the release notes.
When I run shell_exec("whoami"); it prints "nobody"
So why can I run convert by itself, but the "diascope" process can't seem to utilize it? I have tried going into /usr/local/bin/convert and chmoding it to 777, but it didn't seem to have any effect, what else could I try here?
UPDATE: I should probably add that when I try to run diascope -clean audio.txt as root on the terminal, it creates the audio.flv file like it should, also I can't seem to sudo su nobody it returns This account is currently not available.
PHP runs as the same user as apache, which is typically www-data or nobody. I believe you can use suPHP+apache to change the user that PHP runs under.

Trouble running subversion through PHP's exec

I can run an svn command from the command line but not from within a PHP script. Significantly, I can run the PHP script on my Mac and it returns the expected data just fine but when I upload it to my Linux server it won't work (from within PHP... I can run the svn command from the terminal). I'm pretty sure this is a user or permission issue of some sort.
I can run (from command line):
svn log http://whatever.com/svn/foo
but none of the following work (run separately... not all together like this):
exec('svn log http://whatever.com/svn/foo');
exec('svn log http://whatever.com/svn/foo',$out);
exec('/usr/bin/svn log http://whatever.com/svn/foo');
However this works:
exec('ls');
I assume the problem is that when I run from the command line I am running as root whereas when I run from PHP I am running as the apache user (www-data)? Perhaps? Any suggestions on how to be able to run exec('svn log http://whatever.com/svn/foo');?
Changing permissions to 777 (just trying to get it working!) does not help.
Here are a couple of threads that I think might help:
Thread 1 (read as there is more):
$cmd = '/usr/bin/svn list --config-dir /some/place file:///var/subversion/devfoundry/ 2>&1';
exec($cmd, $output);
$output = implode("\n", $output) . "\n";
echo $output;
Thread 2:
The Subversion error "svn: Can't
recode string" can be caused by the
locale being wrong. Try
<?php
putenv('LANG=en_US.UTF-8');
?>
(or whatever your preferred locale is)
before you call shell_exec()
Thread 3: PHP Interactive Shell
May be you can use a svn client for php. Here is a good one
http://code.google.com/p/phpsvnclient/
When you run Subversion from the command line, you are running it as yourself. That is, you are the user logged in and running the command.
If you are running Php from a webpage, it is the user who is running the Apache httpd daemon (which could be "apache", "www", "runwww", etc. depending upon the platform). The user running the PHP script may not have read/write permissions to the Subversion repository.
You have two ways of solving this:
Provide your program with user credentials via the --username and --password command line parameters.
Setup the user running httpd with Subversion credentials. Once it is done, it'll never have to be done again. This way, your PHP code doesn't contain login credentials.

Running shell_exec() in symfony

I have a program that returns a comma-separated string of numbers after doing some background processing. I intended to run this in symfony using shell_exec; however, all I get is NULL (revealed through a var_dump(). I tried the following debugging steps.
I ran the file (it's a PHP class) through a command-line lime unit test in Symfony - it works and gives the correct result there.
Just to check, I tried a simple command ls -l at the same place to see whether I would get anything. Again, I had the same problem - the var_dump in the browser showed NULL, but it worked through the command line.
What could be the problem? Are there restrictions on running shell_exec() in a browser?
EDIT: Just to clarify, shell_exec() commands work when I run them as standalone php scripts on the web server (for example, by putting them in my document root. They don't seem to be working under the symfony framework, for some reason.
I finally solved it, and it turned out to be something quite simple, and quite unrelated.
The shell command I was running was in this format: face_query -D args. I didn't realize that Apache would be executing PHP as user www-data and thus the program face_query wouldn't be in the PATH (the directory is actually ~/bin). Changing the program name to the full path of the program solved it.
I also gather from this that only commands which www-data has permission to execute can be run. In this case, www-data is in the same group as my user, but it might be a problem otherwise.
Have you tried using exec? Or one of the other variants. I am never sure of which one to use and always lump with exec.
http://uk.php.net/manual/en/function.exec.php
Is your web server running php in safe mode?
Note: This function is disabled when PHP is running in safe mode.
From: http://php.net/manual/en/function.shell-exec.php

Categories