2010-12-08 31 views
2

J'utilise PHP CLI via bash shell. Veuillez vérifier Manipulating an array (printed by php-cli) in shell script pour plus de détails.Initialisation de variables dynamiques (variables variables) dans le script shell bash

Dans le code de shell suivant, je suis capable de faire écho les paires key - value que je reçois du script PHP.

IFS=":" 

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

Voici le résultat de cette -

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

Maintenant, je veux juste lancer des variables dynamiques dans la boucle while pour que je puisse les utiliser comme $BASE_PATH ayant une valeur '/path/to/project/root', $db_host ayant 'localhost'

Je viens d'un arrière-plan PHP. Je voudrais quelque chose comme $$key = $val de PHP

Répondre

3

Vous pouvez essayer d'utiliser la construction eval dans 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 

Ensuite, il suffit d'utiliser dans votre boucle.


EDIT: cette boucle de lecture crée un sous-shell qui ne vous permettra pas de les utiliser en dehors de la boucle. Vous pouvez restructurer la boucle de lecture de telle sorte que la sous-shell est pas créé:

# 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 
+0

@Martin merci, cela fonctionne mais il existe un problème de portée variable en dehors de la boucle while. Je suis capable d'écho la variable juste après la ligne eval dans ma boucle, mais pas en dehors du mot-clé 'done' de la boucle' while' –

+0

Vous avez raison, c'est parce que la construction de lecture crée un sous-shell. Ensuite, les variables internes ne seront pas visibles en dehors de la boucle. Je vais mettre à jour la réponse avec une solution alternative ... –

+0

Désolé, cela ne fonctionne pas comme ça. Si je sépare la commande 'while' de la commande' php' (comme vous l'avez fait au lieu de 'php $ PWD '/ test.php' | alors que vous lisez la commande -r, val; do'), la boucle while ne s'exécute qu'une fois et' $ key' et '$ val' sont vides. –

4

L'utilisation eval comportent des risques de sécurité qui doivent être pris en compte. Il est plus sûr d'utiliser 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') 

Si vous utilisez Bash 4, vous pouvez utiliser ces tableaux:

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') 

au moyen du procédé Substition <() et redirigeant dans le done de la boucle while empêche la création d'un sous-shell. Définir IFS pour uniquement la commande read élimine le besoin d'enregistrer et de restaurer sa valeur.

+0

merci pour les conseils mais en utilisant l'une de vos solutions, mon script s'éteint sans rien exécuter (en raison de la partie 'done <<(php $ PWD '/ test.php')'). J'ai essayé de mettre un "echo" avant "' avant la condition while et "echo" après "read simply" après la boucle. Mais rien n'est renvoyé et le script ne demande aucune entrée utilisateur. –

+0

@Sandeepan Nath: Mes exemples de travail varient de la même manière que le deuxième exemple de Martin. Si celui-ci travaille pour vous alors le mien devrait aussi bien. Cela n'a aucun sens que vos tests 'echo' ne fassent rien. Je ne comprends pas pourquoi la substitution de processus redirigée entraînerait la disparition de votre script. –

+1

+1 pour montrer que déclarer peut le faire! Très utile. –