防止在变量中扩展特定空间

Gre*_*yer 4 bash shell-script quoting

在 bash 中,如何避免在变量中扩展特定空间?

可以说我有这个

JAVA_OPTS="-Xmx1g"
JAVA_OPTS="$JAVA_OPTS -XX:OnError='/path/to/a/script.sh %p'"

function args() {
    printf "%d :" $#
    printf " <%s> " $@
    echo
}

args $JAVA_OPTS
Run Code Online (Sandbox Code Playgroud)

你得到这个

3 : <-Xmx1g> <-XX:OnError='/path/to/a/script.sh> <%p'>
Run Code Online (Sandbox Code Playgroud)

我想要这个

2 : <-Xmx1g> <-XX:OnError='/path/to/a/script.sh %p'>
Run Code Online (Sandbox Code Playgroud)

Joh*_*024 9

第一个注意,args即使你只给它一个,也会显示两个参数:

$ args "abc def"
1 : <abc>  <def> 
Run Code Online (Sandbox Code Playgroud)

为了让它正确显示,需要添加双引号:

$ function args() { printf "%d :" $#; printf " <%s> " "$@"; echo; }
$ args "abc def"
1 : <abc def> 
Run Code Online (Sandbox Code Playgroud)

然而,关于 的定义仍然存在问题JAVA_OPTS。观察:

$ args $JAVA_OPTS
3 : <-Xmx1g>  <-XX:OnError='/path/to/a/script.sh>  <%p'> 
Run Code Online (Sandbox Code Playgroud)

这是因为,当$JAVA_OPTS出现在命令行上时,shell 将对 JAVA_OPTS 的内容进行分词,但它不尊重或处理其中包含的引号。

对于这种类型的应用程序,将 JAVA_OPTS 定义为 bash 数组会更好:

$ JAVA_OPTS="-Xmx1g"
$ JAVA_OPTS=("$JAVA_OPTS" "-XX:OnError=/path/to/a/script.sh %p")
$ args "${JAVA_OPTS[@]}"
2 : <-Xmx1g>  <-XX:OnError=/path/to/a/script.sh %p>
Run Code Online (Sandbox Code Playgroud)

顺便说一句,在处理数组时,查看其中内容的一种方便的方法是declare -p

$ declare -p JAVA_OPTS
declare -a JAVA_OPTS='([0]="-Xmx1g" [1]="-XX:OnError=/path/to/a/script.sh %p")'
Run Code Online (Sandbox Code Playgroud)