shell变量不能替换为实际值

时间:2016-01-20 05:36:52

标签: shell

尝试从配置文件中获取字符串,例如

ORACLE_BASE=/a/b
while read line; do
    if [[ $line =~ ^ORACLE_HOME ]]; then
       ORACLE_HOME=`echo $line | sed -e 's/ORACLE_HOME=//g'`
       ORACLE_HOME=$ORACLE_HOME
       echo "ORACLE_HOME=$ORACLE_HOME"
    fi
done < ./conf/setupSM.conf

输出如:

  

ORACLE_HOME = $ {ORACLE_BASE} /product/12.1.0/dbhome_1

但期望的输出应该是:

  

ORACLE_HOME = / A / B /产品/ 12.1.0 / dbhome_1

但$ {ORACLE_BASE}仍然没有被值替换,应该怎样做以使其工作

2 个答案:

答案 0 :(得分:0)

只有一次变量插值。包含其值中另一个变量的变量将不会被展开。

在您的有限情况下,您可以考虑使用eval;或者如果它只是一个可能存在或不存在的变量,请在sed脚本中进行插值:

ORACLE_HOME=`echo "$line" |
    sed -e 's/ORACLE_HOME=//' \
        -e "s/\${\?ORACLE_BASE}\?/$ORACLE_BASE/"`

请注意,/g标志在这里没有任何用处(只有当您需要在同一行上替换多个匹配项时才有用)并正确引用"$line"。您还应该考虑对自己的变量名使用小写,以避免它们与系统变量发生冲突。

shell循环也不是必需或有用的;我会重构sed脚本循环遍历整个文件,并仅打印最后一次出现。这在sed中也不难做到,但我会选择Awk,这只是一种只写的语言。

ORACLE_HOME=$(awk -F= -v b="$ORACLE_BASE" '$1 == "ORACLE_HOME" { o=$2 }
    END { sub("${?ORACLE_BASE}?", b, o); print o }' ./conf/setupSM.conf)

答案 1 :(得分:0)

./conf/setupSM.conf有像

这样的行时
ORACLE_HOME=${ORACLE_BASE}/product/12.1.0/dbhome_1

(无空格或双引号)
并且您希望ORACLE_BASE被评估为您当前的设置,来源您的conf文件(带点):

ORACLE_BASE=/a/b
. ./conf/setupSM.conf
echo "ORACLE_HOME=${ORACLE_HOME}"

这应该给出

ORACLE_HOME=/a/b/product/12.1.0/dbhome_1