Messing up with command-line arguments in Bash: $*, $@, "$*", "$@",…
It’s stupid, but it took me a good hour to figure this out, so maybe I’m not the only one…
I’ve recently had a problem with command-line arguments in my Java program. The problem was that command line arguments containing spaces were parsed incorrectly, i.e. chopped into individual arguments. My initial suspect was gnu.Getopt package I use for parsing arguments, but as it turned out I was wrong.
The real culprit was a shell wrapper script I used to wrap my java code. The code was the following:
java <some parameters> <programm.class> $@
See the problem? I didn’t. You need quotes around "$@" in which case the parameter gets expanded to: "$1" "$2" "$3"... With no quotes the shell expands it to $1 $2 $3, hence all parameters containing spaces get chopped (also globbing takes place in this case).
BTW: There’s also "$*" which is used to combine all parameters into a single one, i.e, "$*" expands to "$1c$2c$3c..., where c is $IFS (or space). Here it’s also important to have it enclosed in quotes.
June 20th, 2006 at 9:33 pm
I just spent an hour trying to figure this out. My problem was that I was using $* instead of $@. Watch out for that!
August 22nd, 2006 at 1:06 am
ah, you just saved me an hour or more
Thanks for sharing!
April 22nd, 2007 at 2:21 am
Nice one. If found the problem with $@ quickly but not the solution (actually I first thought there might be a problem with the parsing library). Of course, in hindsight, a peek at the man page would have helped:
man bash
… @ Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a sepa- rate word. That is, “$@” is equivalent to “$1″ “$2″ … When there are no positional parameters, “$@” and $@ expand to nothing (i.e., they are removed). …
January 17th, 2008 at 10:41 pm
Excellent. This was very useful. Thanks!
July 28th, 2008 at 1:22 pm
I found the problem and the solution after about an hour as well, then discarded the solution because it didn’t look like it was working. I was using ‘echo’ display the expanded java command and parameters, and it seems that echo strips off quotes, so the output looked the same and I assumed it wasn’t going to work.
In this example, the command is:
test.sh -p “a b c”
echo $JAVA_HOME/bin/java com.example.MyClass “$@” —? /usr/java/jdk1.5.0_12/bin/java com.example.MyClass -p a b c
echo $JAVA_HOME/bin/java com.example.MyClass $@ —> /usr/java/jdk1.5.0_12/bin/java com.example.MyClass -p a b c
No difference, I thought, so that back to the drawing board.
BUT, after reading this blog, I tried again and executed with sh -x, I see:
doh!
Thanks!
August 29th, 2009 at 12:13 am
Dude – it’s 2009 and this page is still dolling out love!
Thanks for the tip!