Actually, I am fully understand the use of $* and $@.
For example, if I run the script using: my_script *
Then, for ONE_FILE in $@ will really get each file into ONE_FILE for processing.
Even there is space(s) in the filenames, ONE_FILE will get the correct filename.
If, however, using for ONE_FILE in $*, the story is different.
I think you guys understand the difference and I do not need to go further.
Now, what I am interested is HOW.
How the KornShell (ksh) interprets the my_scrpt *
and then pass the filenames into $@ correctly
and pass the filenames into $*.
For example, when the ksh see my_script *
, does it put the filenames one by one into an array,
and then put the array[1][2][3]… into $@ for processing ?
And, when seeing $*, does it just concat
filename1+space+filename2+space+… ?
I know that this may relate more to the internal coding of ksh.
Any insight?
Yes, pretty much.
One important thing to realize here are that there are two separate processes involved: the calling shell, which expands
my_script *intomyscript arg1 arg2 arg3and the subprocess which gets the array of arguments. If that subprocess isksh(orsh,bash, or a similar shell) then$*is just syntax for “get argv[1…] as a concatenated string” while$@is syntax for “get argv[1…] as an array”. It’s also important to note that$*and$@are only meaningfully different when quoted.In bash, a cousin of ksh, this idea of array variables has actually been generalized. (Perhaps ksh has done this too — I haven’t used ksh for about a decade…)
In bash, this creates an array of 3 elements called
a. Note that the first element contains a space:As you can see from the example,
"${a[*]}"concatenates the array while"${a[@]}"actually gives you the individual elements.