Bash inserting extra, incorrect single quotes when quoting argument list Bash inserting extra, incorrect single quotes when quoting argument list bash bash

Bash inserting extra, incorrect single quotes when quoting argument list


arguments="${*:2}"mvn exec:java -Dexec.mainClass="$1" -Dexec.args="$arguments"

See BashFAQ #50 for a full explanation. That said:

"$@" maintains the split between argv array elements -- which is to say that --foo="$@", when set -- hello world, resolves to "--foo=hello" "world".

"$*" combines argv array elements with the first character of IFS between them, which is by default a space.

$*, without the double quotes, does the same but fails to prevent string-splitting or glob expansion, thus combining all arguments, but then allowing the shell to split them apart again (and expand globs they contain) -- a behavior which is very rarely desirable.

arguments="\"${*:2}\"" creates a string -- "hello world". When you run -Dexec.args=$arguments, this goes through several phases of processing (excluding ones irrelevant to your current dataset, such as glob expansion):

  • Syntactic parsing occurs. It is at this stage, and only at this stage when the shell determines which characters are quoted and how. Because no literal quotes exist in -Dexec.args=$arguments, the only expansion is recorded as unquoted.
  • Expansion occurs. At this point, the expanded string look like -Dexec.args="hello world"
  • String-splitting occurs. Because the parsing stage already processed, recorded and removed syntactic quotes, any quotes remaining are data, and are processed into individual words. Thus, -Dexec.args="hello is a word, and world" is a word.

Compare this to the correct usage, -Dexec.args="$arguments" (or its effective equivalent, "-Dexec.args=$arguments"). At this point:

  • Syntactic parsing occurs. This removes the double quotes around $arguments, and flags the expansion within as double-quoted.
  • Expansion occurs. If you still have literal quotes inside the arguments array, they're substituted in as data, making -Dexec.args="hello world" the literal data passed to Maven, including the quote characters themselves.
  • String splitting occurs on expanded strings. In this case, because syntactic parsing flagged the expansion as double-quoted, it has no effect.

If you don't want literal quote characters passed to Maven (and you shouldn't!), simply omit them, and use only syntactic quotes, as done in the example at the top of this answer.


It appears to be quoting issue. Try this with BASH array:

arr=( "$@" )mvn exec:java -Dexec.mainClass="$1" -Dexec.args="${arr[*]:1}"