2010-12-08 78 views
2

私はbashシェルでPHP CLIを使用しています。詳細はManipulating an array (printed by php-cli) in shell scriptをご確認ください。bashシェルスクリプトでの動的変数(変数変数)の開始

次のシェルコードでは、PHPスクリプトから取得したkey - value個のペアをエコーすることができます。 'localhost'

を持つ、今、私はちょうど私が値 '/path/to/project/root'を持つ $BASE_PATHのようにそれらを使用できるように、whileループ内の動的変数を開始したい

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

$db_host -

IFS=":" 

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

は、このために出力されます

私はPHPの背景から来ました。ちょうどあなたのループ内でそれを使用し、その後

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 

:私はPHP

$$key = $val

答えて

3

あなたはBASHeval構文を使用してみてのような何かをしたいと思います。


EDIT:この読み取りループあなたはループの外でそれらを使用することはできませんサブシェルを作成します。サブシェルが作成されないようにするには、読み取りループを再構築可能性があります

# 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ありがとう、これは動作しますが、whileループの外側には可変スコープの問題があります。ループ内のeval行の直後に変数をエコーすることができますが、whileループの 'done'キーワードの外側には表示されません –

+0

あなたが正しいのは、読み込み構造体がサブシェルを作成するからです。その後、内部変数はループの外側には表示されません。私は別の解決策で答えを更新します... –

+0

申し訳ありませんが、このように動作しません。 'while 'を' php'コマンドから分離した場合( 'php $ PWD'/test.php 'の代わりに' -r key val; do'を実行した場合のように)、whileループは一度だけ実行され、 $ key'と '$ val'は空です。 –

4

evalを使用して考えなければならないセキュリティリスクを紹介します。 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') 

あなたはバッシュ4を使用している場合は、連想配列を使用することができます。

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

プロセスsubstition <()を使用してwhileループのdone作成を防ぐにそれをリダイレクトしますサブシェルのreadコマンドだけにIFSを設定すると、その値を保存して復元する必要がなくなります。

+0

あなたのソリューションを使用していただきありがとうございます。私のスクリプトは何も実行せずに終了します( 'done <(php $ PWD '/ test.php')の部分のため)。私はwhile条件の前に '' echo "を入れ、ループの後に" read simply "の後に' echo "を入れてみました。しかし何もエコーされず、スクリプトはユーザーの入力を促さない。 –

+0

@Sandeepan Nath:私の例題は、Martinの2番目の例と同様に変化します。それがあなたのために働くなら、私のものも同様にすべきです。あなたのテストの 'echo'文が何もしないというのは意味をなさない。私は、リダイレクトされたプロセスの置換があなたのスクリプトを消滅させる理由を理解していません。 –

+1

宣言がこれを行うことができることを示すために+1!非常に便利。 –