Bash脚本属性文件使用'。'在变量名称中

时间:2021-09-20 00:29:21

I'm new to bash scripting and have a question about using properties from a .properties file within a bash script.

我是bash脚本的新手,并且有一个关于在bash脚本中使用.properties文件中的属性的问题。

I have seen a bash properties file that uses'.' between variable names, for example:

我见过一个使用'。'的bash属性文件。变量名之间,例如:

this.prop.one=someProperty

and I've seen them called from within a script like:

我看到他们在一个脚本中调用,如:

echo ${this.prop.one}

But when I try to set this property I get an error:

但是当我尝试设置此属性时,我收到一个错误:

./test.sh: line 5: ${this.prop.one}: bad substitution

I can use properties if I do it without '.' in the variable names, and include the props file:

如果我没有','我可以使用属性。在变量名中,并包含props文件:

#!/bin/bash
. test.properties
echo ${this_prop_one}

I would really like to be able to use '.' in the variable names, and, if at all possible, not have to include . test.properties in the script.

我真的希望能够使用'。'在变量名中,如果可能的话,不必包含。脚本中的test.properties。

Is this possible?

这可能吗?

UPDATE:

Thanks for your answers! Well, then this is strange. I'm working with a bash script that looks like this (a service for glassfish):

谢谢你的回答!那么,这很奇怪。我正在使用一个看起来像这样的bash脚本(glassfish服务):

#!/bin/bash

start() {
        sudo ${glassfish.home.dir}/bin/asadmin start-domain domain1
}

...

...and there are property files like this (build.properties):

...还有像这样的属性文件(build.properties):

# glassfish
glassfish.version=2.1
glassfish.home.dir=${app.install.dir}/${glassfish.target}
...

So, there must be some way of doing this right? Are these maybe not considered 'variables' by definition if they're declared in a properties file? Thanks again.

那么,必须有一些方法来做到这一点吗?如果它们在属性文件中声明,这些可能不被视为“变量”吗?再次感谢。

3 个解决方案

#1


8  

Load them into an associative array. This will require your shell to be bash 4.x, not /bin/sh (which, even when a symlink to bash, runs in POSIX compatibility mode).

将它们加载到关联数组中。这将要求你的shell是bash 4.x,而不是/ bin / sh(即使是bash的符号链接,也在POSIX兼容模式下运行)。

declare -A props
while read -r; do
  [[ $REPLY = *=* ]] || continue
  props[${REPLY%%=*}]=${REPLY#*=}
done <input-file.properties

...after which you can access them like so:

...之后您可以像这样访问它们:

echo "${props[this.prop.name]}"

If you want to recursively look up references, then it gets a bit more interesting.

如果你想以递归方式查找引用,那么它会变得更有趣。

getProp__property_re='[$][{]([[:alnum:].]+)[}]'
getProp() {
  declare -A seen=( ) # to prevent endless recursion
  declare propName=$1
  declare value=${props[$propName]}
  while [[ $value =~ $getProp__property_re ]]; do
    nestedProp=${BASH_REMATCH[1]}
    if [[ ${seen[$nestedProp]} ]]; then
      echo "ERROR: Recursive definition encountered looking up $propName" >&2
      return 1
    fi
    value=${value//${BASH_REMATCH[0]}/${props[$nestedProp]}}
  done
  printf '%s\n' "$value"
}

If we have props defined as follows (which you could also get by running the loop at the top of this answer with an appropriate input-file.properties):

如果我们有如下定义的道具(你也可以通过使用适当的input-file.properties在这个答案的顶部运行循环来获得):

declare -A props=(
  [glassfish.home.dir]='${app.install.dir}/${glassfish.target}'
  [app.install.dir]=/install
  [glassfish.target]=target
)

...then behavior is as follows:

......那么行为如下:

bash4-4.4$ getProp glassfish.home.dir
/install/target

#2


4  

No can do. The bash manual says this about variable names:

没有办法。 bash手册说明了变量名称:

name

A word consisting solely of letters, numbers, and underscores, and beginning with a letter or underscore. Names are used as shell variable and function names. Also referred to as an identifier.

单词由字母,数字和下划线组成,以字母或下划线开头。名称用作shell变量和函数名称。也称为标识符。

Dots not allowed.

不允许点。

#3


1  

dot is not allowed to be variable name. so you cannot just simply source the property file.

dot不允许是变量名。所以你不能只是简单地获取属性文件。

What you can do is:

你能做的是:

"parse" the file, not source it. E.g. with perl, awk or grep to get the value of interesting property name, and assign it to your shell var.

“解析”文件,而不是来源。例如。使用perl,awk或grep来获取有趣的属性名称的值,并将其分配给shell var。

if you do want to set a var with dot in its name, you can use env 'a.b.c=xyz' and get the a.b.c from env output.

如果你想在名称中设置一个带有点的var,你可以使用env'a.b.c = xyz'并从env输出中获取a.b.c。

#1


8  

Load them into an associative array. This will require your shell to be bash 4.x, not /bin/sh (which, even when a symlink to bash, runs in POSIX compatibility mode).

将它们加载到关联数组中。这将要求你的shell是bash 4.x,而不是/ bin / sh(即使是bash的符号链接,也在POSIX兼容模式下运行)。

declare -A props
while read -r; do
  [[ $REPLY = *=* ]] || continue
  props[${REPLY%%=*}]=${REPLY#*=}
done <input-file.properties

...after which you can access them like so:

...之后您可以像这样访问它们:

echo "${props[this.prop.name]}"

If you want to recursively look up references, then it gets a bit more interesting.

如果你想以递归方式查找引用,那么它会变得更有趣。

getProp__property_re='[$][{]([[:alnum:].]+)[}]'
getProp() {
  declare -A seen=( ) # to prevent endless recursion
  declare propName=$1
  declare value=${props[$propName]}
  while [[ $value =~ $getProp__property_re ]]; do
    nestedProp=${BASH_REMATCH[1]}
    if [[ ${seen[$nestedProp]} ]]; then
      echo "ERROR: Recursive definition encountered looking up $propName" >&2
      return 1
    fi
    value=${value//${BASH_REMATCH[0]}/${props[$nestedProp]}}
  done
  printf '%s\n' "$value"
}

If we have props defined as follows (which you could also get by running the loop at the top of this answer with an appropriate input-file.properties):

如果我们有如下定义的道具(你也可以通过使用适当的input-file.properties在这个答案的顶部运行循环来获得):

declare -A props=(
  [glassfish.home.dir]='${app.install.dir}/${glassfish.target}'
  [app.install.dir]=/install
  [glassfish.target]=target
)

...then behavior is as follows:

......那么行为如下:

bash4-4.4$ getProp glassfish.home.dir
/install/target

#2


4  

No can do. The bash manual says this about variable names:

没有办法。 bash手册说明了变量名称:

name

A word consisting solely of letters, numbers, and underscores, and beginning with a letter or underscore. Names are used as shell variable and function names. Also referred to as an identifier.

单词由字母,数字和下划线组成,以字母或下划线开头。名称用作shell变量和函数名称。也称为标识符。

Dots not allowed.

不允许点。

#3


1  

dot is not allowed to be variable name. so you cannot just simply source the property file.

dot不允许是变量名。所以你不能只是简单地获取属性文件。

What you can do is:

你能做的是:

"parse" the file, not source it. E.g. with perl, awk or grep to get the value of interesting property name, and assign it to your shell var.

“解析”文件,而不是来源。例如。使用perl,awk或grep来获取有趣的属性名称的值,并将其分配给shell var。

if you do want to set a var with dot in its name, you can use env 'a.b.c=xyz' and get the a.b.c from env output.

如果你想在名称中设置一个带有点的var,你可以使用env'a.b.c = xyz'并从env输出中获取a.b.c。