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。