Bash脚本从变量添加参数

mai*_*rgs 1 bash shell

我正在研究一个Bash脚本,如果它检测到Java版本大于10,它将添加模块自定义.我似乎无法将自定义作为java命令的参数正确读取

#!/bin/bash


# Expect format:  java full version "10.0.1+10"
jver="$( java -fullversion 2>&1)"

IFS='.-_^+^"'
read -ra ADDR <<< "$jver"    # jver is read into an array as tokens separated by IFS


#java version < 10
if [ ${ADDR[1]} -lt 10 ]; then
    moduleCustomizations=""
else
    moduleCustomizations=("--illegal-access=warn" "--add-opens java.desktop/java.awt.color=ALL-UNNAMED" "--add-opens java.desktop/sun.font=ALL-UNNAMED" "--add-opens java.desktop/java.beans=ALL-UNNAMED" "--add-opens java.base/java.lang=ALL-UNNAMED" "--add-opens java.base/java.lang.module=ALL-UNNAMED" "--add-opens java.desktop/javax.swing=ALL-UNNAMED" "--add-opens java.desktop/java.awt=ALL-UNNAMED" "--add-opens java.desktop/sun.awt.image=ALL-UNNAMED" "--add-opens java.desktop/javax.accessibility=ALL-UNNAMED" "--add-opens java.desktop/sun.awt=ALL-UNNAMED" "--add-opens java.base/jdk.internal.module=ALL-UNNAMED" "--add-opens java.base/java.security.cert=ALL-UNNAMED" "--add-opens java.base/java.security=ALL-UNNAMED" "--add-opens java.base/java.net=ALL-UNNAMED" "--add-opens java.base/java.lang.ref=ALL-UNNAMED")

fi

set -x

java "${moduleCustomizations[@]}"  -Xmx1024m com.test.myClass
Run Code Online (Sandbox Code Playgroud)

通过调试,bash解释为:

java --illegal-access=warn '--add-opens java.desktop/java.awt.color=ALL-UNNAMED' '--add-opens java.desktop/sun.font=ALL-UNNAMED' '--add-opens java.desktop/java.beans=ALL-UNNAMED' '--add-opens java.base/java.lang=ALL-UNNAMED' '--add-opens java.base/java.lang.module=ALL-UNNAMED' '--add-opens java.desktop/javax.swing=ALL-UNNAMED' '--add-opens java.desktop/java.awt=ALL-UNNAMED' '--add-opens java.desktop/sun.awt.image=ALL-UNNAMED' '--add-opens java.desktop/javax.accessibility=ALL-UNNAMED' '--add-opens java.desktop/sun.awt=ALL-UNNAMED' '--add-opens java.base/jdk.internal.module=ALL-UNNAMED' '--add-opens java.base/java.security.cert=ALL-UNNAMED' '--add-opens java.base/java.security=ALL-UNNAMED' '--add-opens java.base/java.net=ALL-UNNAMED' '--add-opens java.base/java.lang.ref=ALL-UNNAMED' -Xmx1024m com.test.myClass
Run Code Online (Sandbox Code Playgroud)

所以我认为问题是单引号出现在除了传递给java命令的第一个项之外的所有项中.我怎样才能让bash正确传递参数?

编辑:

添加另一个方法我尝试将$ moduleCustomizations保持为一个字符串:

#!/bin/bash


# Expect format:  java full version "10.0.1+10"
jver="$( java -fullversion 2>&1)"

IFS='.-_^+^"'
read -ra ADDR <<< "$jver"    # jver is read into an array as tokens separated by IFS


#java version < 10
if [ ${ADDR[1]} -lt 10 ]; then
    moduleCustomizations=""
else
    moduleCustomizations="--illegal-access=warn --add-opens java.desktop/java.awt.color=ALL-UNNAMED --add-opens java.desktop/sun.font=ALL-UNNAMED --add-opens java.desktop/java.beans=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.module=ALL-UNNAMED --add-opens java.desktop/javax.swing=ALL-UNNAMED --add-opens java.desktop/java.awt=ALL-UNNAMED --add-opens java.desktop/sun.awt.image=ALL-UNNAMED --add-opens java.desktop/javax.accessibility=ALL-UNNAMED --add-opens java.desktop/sun.awt=ALL-UNNAMED --add-opens java.base/jdk.internal.module=ALL-UNNAMED --add-opens java.base/java.security.cert=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.lang.ref=ALL-UNNAMED"

fi

set -x

java "${moduleCustomizations}"  -Xmx1024m com.test.myClass
Run Code Online (Sandbox Code Playgroud)

但这变成了:

 java '--illegal-access=warn --add-opens java.desktop/java.awt.color=ALL-UNNAMED --add-opens java.desktop/sun.font=ALL-UNNAMED --add-opens java.desktop/java.beans=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.module=ALL-UNNAMED --add-opens java.desktop/javax.swing=ALL-UNNAMED --add-opens java.desktop/java.awt=ALL-UNNAMED --add-opens java.desktop/sun.awt.image=ALL-UNNAMED --add-opens java.desktop/javax.accessibility=ALL-UNNAMED --add-opens java.desktop/sun.awt=ALL-UNNAMED --add-opens java.base/jdk.internal.module=ALL-UNNAMED --add-opens java.base/java.security.cert=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.lang.ref=ALL-UNNAMED' -Xmx1024m com.test.myClass
Run Code Online (Sandbox Code Playgroud)

而bash将这个论点解释为一个重要论点.

EDIT2:

再次尝试,但这次没有$ {moduleCustomizations}附近的引号.它似乎删除所有破折号:

java '' '' illegal 'access=warn ' '' add 'opens java' desktop/java awt color=ALL 'UNNAMED ' '' add 'opens java' desktop/sun font=ALL 'UNNAMED ' '' add 'opens java' desktop/java beans=ALL 'UNNAMED ' '' add 'opens java' base/java lang=ALL 'UNNAMED ' '' add 'opens java' base/java lang module=ALL 'UNNAMED ' '' add 'opens java' desktop/javax swing=ALL 'UNNAMED ' '' add 'opens java' desktop/java awt=ALL 'UNNAMED ' '' add 'opens java' desktop/sun awt image=ALL 'UNNAMED ' '' add 'opens java' desktop/javax accessibility=ALL 'UNNAMED ' '' add 'opens java' desktop/sun awt=ALL 'UNNAMED ' '' add 'opens java' base/jdk internal module=ALL 'UNNAMED ' '' add 'opens java' base/java security cert=ALL 'UNNAMED ' '' add 'opens java' base/java security=ALL 'UNNAMED ' '' add 'opens java' base/java net=ALL 'UNNAMED ' '' add 'opens java' base/java lang ref=ALL UNNAMED -Xmx1024m com.test.myClass
Run Code Online (Sandbox Code Playgroud)

tha*_*guy 5

问题是你要将两个独立的参数合并在一起:

"--add-opens java.desktop/java.awt.color=ALL-UNNAMED"
Run Code Online (Sandbox Code Playgroud)

不要试图让它变得更难,因为你不会试图运行:

java "--add-opens java.desktop/java.awt.color=ALL-UNNAMED"
Run Code Online (Sandbox Code Playgroud)

只需将java命令后面的任何内容直接放入数组中,而不尝试添加其他引用:

java --add-opens java.desktop/java.awt.color=ALL-UNNAMED
Run Code Online (Sandbox Code Playgroud)

变为:

args=( --add-opens java.desktop/java.awt.color=ALL-UNNAMED )
java "${args[@]}"
Run Code Online (Sandbox Code Playgroud)

在你的代码中:

#!/bin/bash

# Expect format:  java full version "10.0.1+10"
jver="$( java -fullversion 2>&1)"

# jver is read into an array as tokens separated by IFS
IFS='.-_^+"' read -ra ADDR <<< "$jver"    

#java version < 10
if [[ "${ADDR[1]}" -lt 10 ]]; then
    moduleCustomizations=()
else
    moduleCustomizations=(
       --illegal-access=warn
       --add-opens java.desktop/java.awt.color=ALL-UNNAMED
       --add-opens java.desktop/sun.font=ALL-UNNAMED
       --add-opens java.desktop/java.beans=ALL-UNNAMED
       --add-opens java.base/java.lang=ALL-UNNAMED
       --add-opens java.base/java.lang.module=ALL-UNNAMED
       --add-opens java.desktop/javax.swing=ALL-UNNAMED
       --add-opens java.desktop/java.awt=ALL-UNNAMED
       --add-opens java.desktop/sun.awt.image=ALL-UNNAMED
       --add-opens java.desktop/javax.accessibility=ALL-UNNAMED
       --add-opens java.desktop/sun.awt=ALL-UNNAMED
       --add-opens java.base/jdk.internal.module=ALL-UNNAMED
       --add-opens java.base/java.security.cert=ALL-UNNAMED
       --add-opens java.base/java.security=ALL-UNNAMED
       --add-opens java.base/java.net=ALL-UNNAMED
       --add-opens java.base/java.lang.ref=ALL-UNNAMED
    )
fi
set -x
java "${moduleCustomizations[@]}"  -Xmx1024m com.test.myClass
Run Code Online (Sandbox Code Playgroud)

另请注意,set -x输出中出现或未出现的任何引号纯粹是消除歧义的符号.它们不会更改或决定传递给命令的内容.只有这样你的人眼才能分辨出参数数组之间的差异(用Java表示法):

{"hello", "world"}
{"hello", "world", ""}
{"hello world"}
{"hello world", "", ""}
Run Code Online (Sandbox Code Playgroud)

因为如果您只是附加并打印了这些单词,那么所有这些不同的数组都会被读取,hello world并且在调试时它们不是很有用.