PHP exec() not working - permission error?

5.6k Views Asked by At

I'm trying to use exec() to run a program in /var/www/litecoin/bin and echo the output.

Basically, this: (from /var/www/html/index.php)

<?php
   echo exec("../litecoin/bin/litecoin-cli getinfo");
?>

It just shows a blank page, though.

I know it's probably a permission error, as running ls works fine, but I have no idea how to fix it. (or if there's a better way of doing thing)

Running the command directly via the terminal works fine. I'm using PHP7.0 and Apache on Ubuntu 16.04, if it matters.

Edit

It works fine when I run it via the terminal doing php index.php when logged into www-data, but when I open it in the web browser it doesn't seem to execute /var/www/litecoin/bin/litecoin-cli at all.

Edit 2

When redirecting errors from stderr to stdout (2>&1), I get the following:

[0] => 
[1] => 
[2] => ************************
[3] => EXCEPTION: N5boost10filesystem16filesystem_errorE
[4] => boost::filesystem::create_directory: Permission denied: "/.litecoin"
[5] => litecoin in AppInitRPC()
[6] =>

www-data has full permission to /var/www/ though.

2

There are 2 best solutions below

1
Tarun Lalwani On BEST ANSWER

The major difference in such cases i find is the environment and the permissions. The error [4] => boost::filesystem::create_directory: Permission denied: "/.litecoin" suggests that your php page is looking for the folder litecoin in ~ or $HOME and it is not set. That's why it becomes /.litecoin

I created a simple index.php file with below code

<?php

$out = array();
exec("env", $out);

var_dump($out);

The output of same on my default php is

/home/vagrant/nginx/html/index.php:6:
array (size=9)
  0 => string 'APACHE_RUN_DIR=/var/run/apache2' (length=31)
  1 => string 'APACHE_PID_FILE=/var/run/apache2/apache2.pid' (length=44)
  2 => string 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' (length=65)
  3 => string 'APACHE_LOCK_DIR=/var/lock/apache2' (length=33)
  4 => string 'LANG=C' (length=6)
  5 => string 'APACHE_RUN_USER=www-data' (length=24)
  6 => string 'APACHE_RUN_GROUP=www-data' (length=25)
  7 => string 'APACHE_LOG_DIR=/var/log/apache2' (length=31)
  8 => string 'PWD=/home/vagrant/nginx/html' (length=28)

As you can see there is $HOME and that could be one possible reason causing a issue

So you should make sure the correct environment is available to the executable that you are running. You can do that by doing

exec("HOME=/var/www/html X=Y A=B env", $out);

The output of the command shows it can see the updated variables

/home/vagrant/nginx/html/index.php:6:
array (size=12)
  0 => string 'HOME=/var/www/html' (length=18)
  1 => string 'APACHE_RUN_DIR=/var/run/apache2' (length=31)
  2 => string 'APACHE_PID_FILE=/var/run/apache2/apache2.pid' (length=44)
  3 => string 'A=B' (length=3)
  4 => string 'X=Y' (length=3)
  5 => string 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' (length=65)
  6 => string 'APACHE_LOCK_DIR=/var/lock/apache2' (length=33)
  7 => string 'LANG=C' (length=6)
  8 => string 'APACHE_RUN_USER=www-data' (length=24)
  9 => string 'APACHE_RUN_GROUP=www-data' (length=25)
  10 => string 'APACHE_LOG_DIR=/var/log/apache2' (length=31)
  11 => string 'PWD=/home/vagrant/nginx/html' (length=28)

Figure out which environment variables you need and make sure they exists and try to set the paths so your executable used /var/www or /var/www/html whichever path it has access to and then executes the program

8
Nigel Ren On

Using exec() and just echoing out the return value may miss the main content of the output as it will only return the last line of the output. On my computer if I run

echo exec("ls");

I get the output...

xsl.php

If you add a second paramter to exec(), all the output is sent to that paramter . So...

exec("ls", $output);
print_r($output);

outputs...

Array
(
    [0] => Copy of data.xml
    [1] => Copy of test.json
    [2] => NewFile.html
    [...] // Shortened for example
    [35] => xsl.php
)

If your command has a blank line as the last line of output, that is all you'll see. To ensure you see all the content...

exec("../litecoin/bin/litecoin-cli getinfo", $output );
print_r($output);

I would also (in this case) change the exec to use the absolute path to make sure I know what is being run and where from...

exec("/var/www/litecoin/bin/litecoin-cli getinfo", $output );

As for permissions, your apache server is run as www-data:www-data, so ensure that this user is allowed to execute the scripts. There are several solutions to this, the simplest way would be to ensure that this user owns all of these files.

chown -R www-data:www-data /var/www/litecoin