0

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.

hhaslam11
  • 191
  • 2
  • 7
  • 24
  • I think the issue is the env being different. You should try running `$out = array(); exec("env", $out); var_dump($out);` and see if `HOME` environment variable is missing? I think it an issue of environment variables not be properly set in your case – Tarun Lalwani Mar 25 '18 at 10:20

2 Answers2

2

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
Nigel Ren
  • 56,122
  • 11
  • 43
  • 55
  • I did all this, but I still can't get it to work. I just get an empty array. It doesn't seem to be an error with getting output, as it doesn't run the executable in the first place. – hhaslam11 Mar 18 '18 at 02:58
  • Okay, it works fine when I run it via terminal, but when I run it through the web browser it doesn't work. – hhaslam11 Mar 18 '18 at 03:00
  • Can you try running from cli whilst logged in as www-data ( may have to do `sudo su -s /bin/bash www-data` ) – Nigel Ren Mar 18 '18 at 07:41
  • I get EXCEPTION: N5boost10filesystem16filesystem_errorE boost::filesystem::create_directory: Permission denied: "/var/www/.litecoin" litecoin in AppInit() litecoind: chainparamsbase.cpp:69: const CBaseChainParams& BaseParams(): Assertion `globalChainBaseParams' failed. Aborted (core dumped) – hhaslam11 Mar 18 '18 at 08:28
  • OK, so now check ownership of the /var/www/.litecoin file and change it to www-data if necessary. – Nigel Ren Mar 18 '18 at 08:29
  • It says /var/www/.litecoin doesnt exist. I think it's trying to create that file, if im not mistaken. But I gave www-data permission to read and right to the directory, so it should work fine? – hhaslam11 Mar 18 '18 at 08:33
  • Does it have 777 permission, not ideal, but can check to see what's happening. – Nigel Ren Mar 18 '18 at 08:36
  • Okay, so I got it working with 777 permission when running the php file from the terminal logged in with www-data; but it still shows an empty array when doing it from the web browser. – hhaslam11 Mar 18 '18 at 09:00
2

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

Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
  • 1
    This seems to be the problem, thanks! Why are the environment variables different when ran through the browser, as opposed to running it in the terminal while logged in as www-data? Shouldn't it be the same? – hhaslam11 Mar 26 '18 at 00:40