I’ve been working in a little project to create HTML representations of certain processes / infrastructure in our company.

Because I wanted to make something easy to maintain, I decided to create a unique configuration file with all the paths (variables) for both bash and PHP scripts.

Let’s take a look at the files to have a better understanding of the proposed solution. This is my file with variables for the bash script (and I will need it for the php as well):

# List of variables for bash and php in .sh file

BASE_PATH=/var/www/html/project
BASH_PATH=$BASE_PATH/bash
PHP_PATH=$BASE_PATH/php

#etc...

One of the easiest solutions was to bring the file with variables to PHP using the function parse_ini_file() but that raised a new problem.

<?php
/*bring our bash variables to PHP*/
$config = parse_ini_file("/var/www/html/project/bash/_all_config_vars.sh", true);
extract($config);

echo $BASE_PATH:}
echo '<p></p>';
echo BASH_PATH;        
?>

The variables to be interpreted by the shell are being printed as plain text, this is the HTML output of PHP:

/var/www/html/project
$BASE_PATH/bash

At this point you can do two things, one is to make absolute paths in the original script (which I don’t find really nice) or parse the string and resolve the variable into PHP (which would add complexity to a problem that doesn’t need it).

I’ve tried using eval() to resolve the variable $BASE_PATH but that won’t happen because there is no spaces between it and the /bash part. Despite the fact the variable is in a string If I had a blank space between $BASE_PATH and /bash then it would be possible to resolve it using eval(), but this is clearly not the case. Also I found this in the PHP website:

If eval() is the answer, you’re almost certainly asking the wrong question. — Rasmus Lerdorf, BDFL of PHP

Other solution could be executing the shell inside the PHP and getting the variables from the environment like explained in this example:

function render()
{
	$cmd = "sh /var/www/html/project/bash/_all_config_vars.sh";

    system($cmd);

    echo getenv("BASE_PATH");
    echo getenv("BASH_PATH");
}

render();

But that force us to use PHP in an insecure way enabling it to run shell scripts, that would bring security problems in certain environments.

My solution

Then I thought one nice solution would be to process the variables with the shell and printing the output. To do that I’ve exported the variables to the environment (they will be declared as well for the bash scripts that call them). The nice thing about export is that it won’t change the current behavior of the variables but add them into the environment temporarily.

Also I’ve added a prefix «TPR_»  (This PRoject) so it will be easier to catch the variables processed using «printenv» and «grep»:

# List of variables for bash and php in .sh file

export TPR_BASE_PATH=/var/www/html/project
export TPR_BASH_PATH=$BASE_PATH/bash
export TPR_PHP_PATH=$BASE_PATH/php

printenv | grep TPR_ > /var/www/html/project/processed_vars.out
#etc...

So the output file looks like:

BASE_PATH=/var/www/html/project
BASH_PATH=/var/www/html/bash
PHP_PATH=/var/www/html/php

And because they are absolute paths now, I’ll be able to use parse_ini_file() with the file processed_vars.out without the problem of unresolved variables allowing me to have the flexibility to maintain the bash and php scripts from one source file.

The variables will be available just in the runtime so our S.O environment won’t be filled with them. Of course in my scenario the bash scripts always run first than the php code.