mainstringargs
mainstringargs

Reputation: 14371

Bash script adding arguments from variable

I'm working on a Bash Script that will add module customization if it detects that the Java version is greater than 10. I can't seem to get the customizations to be read in properly as a parameter to the java command

#!/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

Which through debug, bash interprets as:

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

So I believe the problem is that the single quotes are appearing in all but the first item passed to the java command. How can I get bash to properly pass the arguments?

EDIT:

Adding another method I've tried keeping $moduleCustomizations as one string:

#!/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

But this turns into:

 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

And bash interprets the argument as one big argument.

EDIT2:

Trying again but this time without quotes around ${moduleCustomizations}. It seems to remove all dashes:

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

Upvotes: 1

Views: 528

Answers (1)

that other guy
that other guy

Reputation: 123410

The problem is that you're merging together what should be two separate arguments:

"--add-opens java.desktop/java.awt.color=ALL-UNNAMED"

Don't try to make it harder than it is, because you wouldn't try to run:

java "--add-opens java.desktop/java.awt.color=ALL-UNNAMED"

Just put whatever you would add after the java command directly inside the array without trying to add additional quoting:

java --add-opens java.desktop/java.awt.color=ALL-UNNAMED

becomes:

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

In your code:

#!/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

Also note that any quotes that do or don't appear in set -x output are purely disambiguation notation for your benefit. They don't change or decide what's being passed to the command. It's just so that your human eyes can tell the difference between argument arrays like (in Java notation):

{"hello", "world"}
{"hello", "world", ""}
{"hello world"}
{"hello world", "", ""}

Because if you just appended and printed the words, all these different arrays would read hello world and that's not very helpful when debugging.

Upvotes: 5

Related Questions