Using $@ properly Using $@ properly unix unix

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 "$@"