PHP exec fails with rsync

PHP has an exec function which lets you run a program. Why would you want to use a PHP program to run a different program? You might want to run a file listing using ls, or copy files using cp, for example. When using exec, you need to be thoughtful of the environment in which PHP is running. A command line script that you run from a terminal, like php test.php, runs in a different environment than a php file run by Apache in responding to a web request. This post will take a look at the difference.

Suppose we have a little PHP file called whoami.php which runs the Linux whoami command:

<?php
  $result = exec("whoami", $output, $retVar);
  echo "Output:".print_r($output, TRUE)."\n";
  echo "retVar:".print_r($retVar, TRUE)."\n";
?>

When I run this as a script from the command line, php whoami.php, I see this output:

Output:Array
(
    [0] => fullstackdev
)

retVar:0

As expected, whoami returns fullstackdev – that’s my user name on my computer.

If I put this file into my Apache root directory and run it by surfing to http://localhost/whoami.php, I see something different in my browser:

Output:Array ( [0] => www-data ) retVar:0

If you have Apache up and running, you might want to try this for yourself.

At first, seeing this output may seem strange. Why does whoami return a different value when I run this script in the browser? The answer is that it’s not “me” running the script. It’s Apache, or more accurately, the “Apache user”. When Apache was installed on my system (Ubuntu 16.04), an Apache “user” was created which is responsible for running the Apache web server process. This user is named “www-data”.

You can also see who the Apache user is by listing the Apache processes from the command line with ps -ef|grep apache (or ps -ef|grep httpd). Here’s the output on my system, which again shows the Apache user being “www-data”:

ps -ef|grep apache
..
www-data 29172 29963  0 07:35 ?        00:00:00 /usr/sbin/apache2 -k start
...

This is something to keep in mind when comparing the results of a PHP script that you run in the browser versus one you run from the command line.

Usually, when running PHP scripts as Apache, it’s not relevant that “www-data” is running that script.

But there are cases where it does matter, and the PHP exec function can be one of them. For example, if your PHP script uses exec to ssh, rsync, or touch files in your own personal .ssh directory, you will probably run into trouble. The “www-data” user does not have access to your .ssh files. That user may not even have its own home directory, where .ssh would normally be located.

Here’s one final tip. If you’re trying to run commands that use passwordless ssh from Apache, you may want to rethink what you’re trying to do. There may be other ways to do what you want: cron jobs, or watch scripts.

If you found this interesting, click the subscribe button below! I write a new post about once a week.

Leave a Reply

Your email address will not be published. Required fields are marked *