2

我有一个 PHP 脚本,它将像这样以管道分隔的变量列表导出到 STDOUT:

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

我想要做的是将它们读入 Bash 脚本并将它们设置为 shell 变量,以供从 shell 脚本内部调用的任何程序使用,即

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

这是我所做的,但不起作用:

#!/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.

我已经确认设置的 env 字符串没有任何空格或特殊字符。但是无论我传递给 eval 的参数是什么排列,变量都不会被设置。

有任何想法吗?在 bash 中以编程方式创建新的 shell 变量是否存在安全块?

4

2 回答 2

4

这就是你所需要的。

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

为了测试,我用 get_env.sh 替换了 get_env.php

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

然后当我运行下面的命令时,我得到以下输出。

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

在 html 表单将 names=values 提交到您的 php 脚本并将这些发送到您的 bash 脚本的情况下,为变量名添加一些内容可能是一种安全措施。

于 2014-04-20T08:55:52.993 回答
2

可能这个常见的 bash陷阱Bash 有时可以在 PIPED 'while-read' 循环中启动一个子 shell
这会导致 while-read 循环中引入的变量消失。

通常的解决方案是存储变量并在循环外使用它们。

于 2013-05-25T18:05:03.743 回答