Bash 在shell脚本中将${}占位符解析为绝对路径

Bash 在shell脚本中将${}占位符解析为绝对路径,bash,shell,properties,Bash,Shell,Properties,我有一个app.properties文件,如下所示 Base.dir="/user/test/application" Result.dir="${base.dir}/result" 我已经创建了bash脚本来解析上述属性 function readConfigFile() { (grep -E "^${2}=" -m 1 "${1}" 2>/dev/null || echo "VAR=__UNDEFINED__") | head -n 1 | cut -d '=' -f 2-; }

我有一个app.properties文件,如下所示

Base.dir="/user/test/application"
Result.dir="${base.dir}/result"
我已经创建了bash脚本来解析上述属性

function readConfigFile()
{
  (grep -E "^${2}=" -m 1 "${1}" 2>/dev/null || echo "VAR=__UNDEFINED__") | head -n 1 | cut -d '=' -f 2-;
}

function setConfigFile()
{
    sourceFile=${1}
}

function configGet()
{
    if [ ! -z $sourceFile ]; then
        val="$(readConfigFile $sourceFile "${1}")";
        if [ "${val}" = "__UNDEFINED__" ]; then
            echo "${1} value not exist"
            # return empty string
            printf -- "%s" "";
        fi
        printf -- "%s" "${val}";
    else
        echo "config file not exist"
        # return empty string
        printf -- "%s" "";
    fi
}
我在上面调用解析器的方式如下

$Result_dir=$(configGet Result.dir)
但是,我无法将占位符${}转换为base_dir

我得到了以下错误

ls $Result_dir
ls: cannot access ${Base_dir}/result: No such file or directory

有什么方法可以把${Base.dir}翻译成/user/test/application吗?

我想你不能用
${Base.dir}
(顺便说一句,应该是
${Base.dir}
)来代替你希望的方式,主要是因为,据我所知,在bash中变量名中不允许点

您可以使用bash的替换语法手动将
${base.dir}
部分替换为相应的路径。例如:

setConfigFile 'app.properties'

Result_dir_raw=$(configGet Result.dir)
Result_dir=${Result_dir_raw/'${base.dir}'/$(configGet Base.dir)}

echo ${Result_dir}
我之所以说“手动”,是因为您仍然在源代码中指定要替换的模式是
${base.dir}
,我猜这不是您想要的


现在,如果您运行它,您将看到
${Result\u dir}
变量的计算结果为
“”/user/test/application/Result“
,这显然不是一个路径,这是因为您在
app.properties
中用双引号括起了路径,因此,您要么需要在
readConfigFile
函数中删除它们,要么在配置文件中完全丢失它们,这对我来说更有意义。

为什么在变量名中有
,这在
bash
中是不允许的:

$ Base.dir="/user/test/application"
-bash: Base.dir=/user/test/application: No such file or directory
$ Base_dir="/user/test/application"
$
那么,为什么没有这样的文件或目录呢?下面是一个解释:

创建一个名为
Base.dir=gash.sh的文件,是的,这是一个合法的文件名

$ echo 'echo Hello World' > Base.dir=gash.sh
使文件可执行:

$ PATH=$PATH:.
$ chmod u+x Base.dir=gash.sh
现在键入命令:

$ Base.dir="gash.sh"
Hello World

使用下划线,而不是点。顺便说一句,
ksh
Korn shell不仅允许点,它还有一个特殊的含义,它是一个复合变量。

正如下面的答案所指出的,问题在于属性名称中的
。它似乎是一个Java
.properties
文件,您可能无法轻松更改命名方案。因此,在将
app.properties
馈送到
configGet
之前,您必须对其进行预处理,例如
cat$1 | tr.“| | | grep-e…”
(这不太理想,因为如果属性值中有
,它将无法正常工作。另一种选择是
sed
)@hosseinpurtani,这是java属性文件,我会给它tryit实际上是java属性文件,我通过调用我的解析器方法Base_dir=$(configGet Base.dir)将其转换为bash变量的方式,这是导致问题的变量名,而不是文件名。当然,在Java中,点是一个运算符(用于名称空间遍历和字段访问),因此也不允许将其作为变量名的一部分。对了,我还认为很难自动替换${}占位符,谢谢您的解决方案