2

I have a PHP script which exports a pipe-delimited list of variables like this to STDOUT:

DB_HOST|localhost
DB_DATABASE|mydb
DB_USER|postgres
...

What I want to do is read them into a Bash script and set them as shell variables to be used by any programs called from inside the shell script, i.e.

psql -U $DB_USER -h $DB_HOST -d $DB_DATABASE <<END_OF_SQL
  code...
END_OF_SQL

Here's what I did, which isn't working:

#!/bin/bash

# We don't need an eval here but just to confirm that it works with eval.
eval export FOO_DOCROOT=/web/gallery

php get_env.php | while read X
    do
    LINE=(`echo $X | tr "\|" "\n"`)
    V="${LINE[0]}=${LINE[1]}"   # Outputs a string, i,e. "FOO_DBHOST=localhost".
    echo "V=$V"
    echo $V
    # This has no effect.
    eval export $V
done;

echo Check the environment
echo /bin/env:
env

# env has FOO_DOCROOT set correctly
# but none of the evals in the DO/DONE loop are set.

I've confirmed that the set env strings don't have any whitespace or special characters. But no matter what permutation of arguments I pass to eval the variables don't get set.

Any ideas? Is there a security block with creating new shell variables programmatically in bash?

2 Answers 2

4

This is all that you need.

#!/bin/bash
# script name script1.sh
while IFS="|" ; read VarName Value; do
    export Imported_$VarName=$Value
done
echo Check Enviroment
env |grep DB_

For testing I substituted get_env.php with get_env.sh

#!/bin/bash
# script name get_env.sh
echo "DB_HOST|localhost
DB_DATABASE|mydb
DB_USER|postgres"

Then when I run the command below, I get the following output.

~$ ./get_env.sh |./script1.sh 
Check The Environment
Imported_DB_USER=postgres
Imported_DB_DATABASE=mydb
Imported_DB_HOST=localhost

Prepending something to variable name can be a security measure in cases where a html form submits names=values to your php script and those are sent to your bash script.

Sign up to request clarification or add additional context in comments.

Comments

2

Probably this common bash gotcha
Bash can sometimes start a subshell in a PIPED `while-read' loop. This causes variables introduced within the while-read loop to disappear.

The usual solution is to store the variables and use them outside the loop.

1 Comment

Excellent find, Nifle. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.