Command-Line Arguments in Shell Scripts
There are a few ways to loop over command-line arguments in shell scripts.
$@, and then there are quoted (
"$@") versions of
each. Each one behaves differently, but there’s one that you almost always want
Here’s a shell script named
demo.sh that will illustrate the difference:
#!/bin/sh for argument in $*; do echo "$argument" done
(For each bit about
"$@", assume I changed the
part of the script accordingly.)
$* will ignore quotes in arguments:
# $* $ ./demo.sh "keep it together" two keep it together two
This behaves exactly like
./demo.sh keep it together two. We want it to print
keep it together and
two as separate lines, so this is wrong.
Now let’s try with
# $@ $ ./demo.sh "keep it together" two keep it together two
$@ acts exactly like unquoted
Now let’s try it with
# "$*" $ ./demo.sh "keep it together" two keep it together two
As you can see, it combined the two arguments into one long argument
Technically, it’s joining the two arguments with the
$IFS (or “internal field
separator”) variable. By default,
"$IFS" is three characters: a space, a tab,
and a newline.
"$*" only joins with the first character of
$IFS, so it print
the arguments with a space between them, but we can temporarily change it:
#!/bin/sh IFS="GABE" for argument in "$*"; do echo "$argument" done
$ ./demo.sh "keep it together" two keep it togetherGtwo
In any case, it’s still not quite there, so let’s keep looking.
And finally, the one that we always want to use,
# "$@" $ ./demo.sh "keep it together" two keep it together two
At last, we have printed two lines for two arguments, appropriately split up according to how we passed them in as arguments.