Using $@ properly
Here is a demonstration of the some of the differences between $*
and $@
, with and without quotes:
#/bin/bashfor i in $*; do echo "\$*: ..${i}.."done; echofor i in "$*"; do echo "\"\$*\": ..${i}.."done; echofor i in $@; do echo "\$@: ..${i}.."done; echofor i in "$@"; do echo "\"\$@\": ..${i}.."done; echo
Running it:
user@host$ ./paramtest abc "space here"$*: ..abc..$*: ..space..$*: ..here.."$*": ..abc space here..$@: ..abc..$@: ..space..$@: ..here.."$@": ..abc.."$@": ..space here..
How about this one:
for filedo test -f "$file" && ls -l "$file"done
The for loop by default will work on $@, so you don't have to mention it. Note that you will need to quote "$file" in case if the file name has embedded space. For example, if you save your script to 'myll.sh':
$ myll.sh "My Report.txt" file1 file2
Then "My Report.txt" will be passed in as a whole token instead of 2 separate tokens: "My" and "Report.txt"
The variable you want is indeed $@
- this contains all command-line arguments as separate words, each passed on intact (no expansion). ($*
treats all of them as a single word - good luck sorting it out if you have spaces in filenames).
You can loop, if you like. This is easily expanded to more complex actions than ls
.
for file in "$@"; do if [ -f "$file" ]; then ls -l "$file" fidone
Note: you should quote $@
to protect any special characters inside! You should also quote $file
for the same reason - especially inside the test. If there is an empty string in $@
, file
will also be empty, and without quotes, -f will attempt to act on the ']'. Errors ensue.
Also, if all you need to do is ls
(skipping your if
) you can just do this:
ls -l "$@"