On Tuesday 15 May 2007 18:59:08 Roshan wrote:
#!/bin/sh
for f in $*; do convert -resize 640x480 $f t-$f done
I have one question. Is the $* is for argument number (or its type) for the file that would have to be converted?
$* expands the positional parameters.
Positional parameters are arguments passed to a command. When you run your script by doing, say,
$ ./image-resize image1 image2 image3
the positional parameters get set to ./image-resize, image1, image2 and image3.
The positional parameters can be used as the variables $0 to $n where n is any integer. $0 is always set to the name of the script, in this case image-resize. The parameters from $1 onwards are the actual arguments. So in this case,
$1 == image1 $2 == image2 and $3 == image3
These are read only variables. You can't manually assign a value to them. You must use either set or shift.
When you process the arguments, you can either call them individually, or, as is most common, process them in a loop, one by one. You've used the second method.
$* and $@ are two variables that can be used to query all the positional parameters together. When unquoted, they are subject to IFS word splitting like any other variable in bash. What this means is that if your arguments have spaces or newlines embedded in them, they'll be split up to be two different entities.
The safe way is to double quote ( " ) the variables, which prevents this internal splitting.
Now it'll take a couple of chapters from a book if I were to explain all the `theory' behind this, so I'll skip it all and leave it to you to learn. I'll just say though, for any normal processing of arguments, 99% of the times, you'd want to use "$@". Mind the double quotes. VERY important.
Here's an example:
$ set "foo bar" baz blah $ # "foo bar" is intended to be a single argument. $ # set can be used to set various bash options and positional parameters. $ echo $1 foo bar $ echo $2 baz $ echo $3 blah $ for i in $@; do echo '==> '${i}' <=='; done ==> foo <== ==> bar <== ==> baz <== ==> blah <== $ # Notice that foo and bar have been split up. Undesirable. $ for i in $*; do echo '==> '${i}' <=='; done ==> foo <== ==> bar <== ==> baz <== ==> blah <== $ # When unquoted $@ and $* produce the same result. $ for i in "$@"; do echo '==> '${i}' <=='; done ==> foo bar <== ==> baz <== ==> blah <== $ # I suppose this is what you wanted? $ for i in "$*"; do echo '==> '${i}' <=='; done ==> foo bar baz blah <== $ # When double quoted, $@ and $* differ vastly.. $ # And that's not the result you wanted either. $ # Always use "$@".