I am using PHP CLI through bash shell. Please check Manipulating an array (printed by php-cli) in shell script for details.

In the following shell code I am able to echo the key- value pairs that I get from the PHP script.

IFS=":"

# parse php script output by read command
php $PWD'/test.php' | while read -r key val; do
    echo $key":"$val
done

Following is the output for this -

BASE_PATH:/path/to/project/root
db_host:localhost
db_name:database
db_user:root
db_pass:root

Now I just want to initiate dynamic variables inside the while loop so that I can use them like $BASE_PATH having value '/path/to/project/root', $db_host having 'localhost'

I come from a PHP background. I would like something like $$key = $val of PHP

share|improve this question

2 Answers

up vote 2 down vote accepted

You may try using the eval construct in BASH:

key="BASE_PATH"
value="/path/to/project/root"
# Assign $value to variable named "BASE_PATH"
eval ${key}="${value}"

# Now you have the variable named BASE_PATH you want
# This will get you output "/path/to/project/root"
echo $BASE_PATH

Then, just use it in your loop.


EDIT: this read loop creates a sub-shell which will not allow you to use them outside of the loop. You may restructure the read loop so that the sub-shell is not created:

# get the PHP output to a variable
php_output=`php test.php`

# parse the variable in a loop without creating a sub-shell
IFS=":"
while read -r key val; do
    eval ${key}="${val}"
done <<< "$php_output"

echo $BASE_PATH
share|improve this answer
@Martin thanks, this works but there is variable scope issue outside the while loop. I am able to echo the variable right after the eval line inside my loop, but not outside the done keyword of the while loop – Sandeepan Nath Dec 8 '10 at 7:54
You are right, that's because the read construct creates a sub-shell. Then the inner variables will not be visible outside of the loop. I will update the answer with alternative solution... – Martin Kosek Dec 8 '10 at 8:10
Sorry it does not work like this. If I separate the while from the php command (like you have done instead of php $PWD'/test.php' | while read -r key val; do), the while loop executes only once and $key and $val are empty. – Sandeepan Nath Dec 8 '10 at 10:02
also please tell me what does the done <<< "$php_output" statement do? I have no variable called $php_output. Is it a keyword? If I keep the while loop and the php command together (like in my question) and just add this <<< "$php_output" or <<< "$BASE_PATH", the variables do not echo inside as well as outside the loop. – Sandeepan Nath Dec 8 '10 at 10:09
php_output is just a variable I declared in my second example (first command). <<< "$php_output" redirects the content of variable $php_output to the while loop What happens if you run the code I suggested, does it work? It works for me... – Martin Kosek Dec 8 '10 at 10:20
show 1 more comment

Using eval introduces security risks that must be considered. It's safer to use declare:

# parse php script output by read command
while IFS=: read -r key val; do
    echo $key":"$val
    declare $key=$val
done < <(php $PWD'/test.php')

If you are using Bash 4, you can use associative arrays:

declare -A some_array
# parse php script output by read command
while IFS=: read -r key val; do
    echo $key":"$val
    some_array[$key]=$val
done < <(php $PWD'/test.php')

Using process substition <() and redirecting it into the done of the while loop prevents the creation of a subshell. Setting IFS for only the read command eliminates the need to save and restore its value.

share|improve this answer
thanks for the tips but using either of your solutions, my script dies out without running anything (due to the done < <(php $PWD'/test.php') part). I tried putting an echo "before" before the while condition and echo "after" read simply after the loop. But nothing is echoed and the script does not prompt for any user input. – Sandeepan Nath Jan 4 '11 at 10:09
@Sandeepan Nath: My examples work vary similarly to Martin's second example. If that one works for you then mine should as well. It doesn't make any sense that your test echo statements don't do anything. I don't understand why the redirected process substitution would cause your script to die out. – Dennis Williamson Jan 4 '11 at 15:35

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.