2

I'm trying to create a bash script that will build a list of arguments before calling java, but I am having trouble getting a classpath argument with a wild card to work. The script so far:

#!/bin/bash
PROP_FILES=./props/default.properties
#EXTRA_PROP_FILES_HERE

ARGS="-cp \"lib/*\""
ARGS="$ARGS -Xmx10G"
ARGS="$ARGS -Duser.timezone=GMT"
ARGS="$ARGS -Danl.property.files=$PROP_FILES"

java $ARGS main.class.path.Main

The problem is with the ARGS="-cp \"lib/*\"". I'm debugging the file with the command bash -x runscript.sh.

If I escape the wildcard cp (like in the script above), the script fails with the output (note the extra single quotes):

java -cp '"lib/*"' ...

If I don't escape it, the * expands to all of the jars in the lib directory and also fails

How do I modify the script so that it calls this?

java -cp "lib/*" ...

Note: I know I could just do java -cp "lib/*" $ARGS ..,, but I'd really like to get this working.

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
lucasvw
  • 1,345
  • 17
  • 36
  • There *is* a shell option to turn off glob expansion altogether (see `help set` for a list -- the pertinent option is `set -f`), but that doesn't fix the other issues discussed in BashFAQ #50. "Use a proper array" is very much the Right Thing. – Charles Duffy Dec 10 '18 at 16:20

1 Answers1

5

You should use an array with proper quoting:

propfiles='./props/default.properties'

args=(-cp 'lib/*')
args+=(-Xmx10G -Duser.timezone=GMT)
args+=("-Danl.property.files=$propfiles")

java "${args[@]}" main.class.path.Main

Also, using uppercase variable names makes it more likely to clash with environment variables, so it's best avoided.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
  • Thanks, I'll give it a try! Is there no way to do it with basic strings? – lucasvw Dec 10 '18 at 16:15
  • No. I wrote a [very detailed answer](https://stackoverflow.com/a/53673083/68587) recently explaining exactly why not. – John Kugelman Dec 10 '18 at 16:16
  • 1
    ...it doesn't help that there are a lot of very prominent Java projects (*ahem* Tomcat *ahem*) doing it the Wrong Way, but... well, those projects are wrong, and the approach they follow (in their wrapper shell scripts) is buggy. (I blame cargo-culting -- the first Java project wrote their wrapper that way, and then the next one copied it without actually understanding the code, repeat ad infinitem). – Charles Duffy Dec 10 '18 at 16:17
  • @lucasvw See also [BashFAQ/050](https://mywiki.wooledge.org/BashFAQ/050). – Benjamin W. Dec 10 '18 at 16:17