Convert a list of bash arguments to a quoted single string

2k Views Asked by At

I'm trying to create a simple bash script to run a mvn command with some specific arguments and "sub" arguments, using the exec plugin. Seems simple, but I'm having problems to achieve the desired effect:

here is the command to run:

mvn exec:java -Dexec.args="-a val1 -b val2 -c val3"

it works fine when run like this, but I want to wrap it in a bash script, easy to run for everyone:

myapp -a val1 -b val2 -c val3

The script would be as easy as:

mvn exec:java -Dexec.args="$@"

But "$@" doesn't make it a single quoted value, so I tried to quote it:

mvn exec:java -Dexec.args=\""$@"\"

I also tried a second script I called quoter:

./myapp \""$@"\"

This doesn't work either, after a good combination playing time around, it feels like no matter how many times I quote it, it still treats it as a list of arguments, being the first element "-a, then the second element val1, then third -b, and so on.

curiously, if I don't quote the arguments in the quoter script, and run it like this:

./quoter "-a val1 -b val2 -c val3"

It works fine, it is passed as a single parameter to the second script and then to the first script executing the maven command.

It seems like, "$@" is not quite a string made of the stringficated concatenation of all the parameters (which is cool if you think about it), nor echoing it seems to convert it into one (not cool). Is there a way to make this possible?

PS: yes I'm trying to pass options to the main program, which is a heavily dependent spring standalone application.

2

There are 2 best solutions below

2
On

man bash...

Special Parameters
  The shell treats several parameters specially. These parameters may only be
  referenced; assignment to them is not allowed.
  *  Expands to the positional parameters, starting from one.  When the expansion
     occurs within double quotes, it expands to a single word with the value of
     each parameter separated by the first character of the IFS special variable.
     That is, "$*" is equivalent to "$1c$2c...", where c is the first character
     of the  value  of  the  IFS variable.  If IFS is unset, the parameters are
     separated by spaces.  If IFS is null, the parameters are joined without
     intervening separators.
0
On

Ok, after some more hours I found a solution, here it is. I created whole new script so I'll start from the scratch.

Create a simple script that the final user will execute and pass the parameters as a normal command-line app:

$./myapp -a val1 -b val2 -c val3

which will contain the following:

mvn exec:java -Dexec.args="$*"

The difference between $* and $@, is that $@ will pass the arguments as a list and will also do some formatting to those values, like removing quotes and so. In the other hand, $* will treat all the arguments as a single one, grouping them and letting you pass them altogether as a string value to the inner command.