Can someone interpret this -- not sure

Was wondering if someone could interpret this for me -- I'm not sure what everything means. It's a shell script from my bash book:

cd ()
{ 
     builtin cd "$@"
     es=$?
     echo "$OLDPWD ->$PWD"
     return $es
}

what I don't quite understand is the "$@". I think, if I understand it correctly, it is all the positional parameters to the function, as separate double quoted strings separated by spaces.

The function works fine, but how does it interpret a directory with more than one word? Is each word in the directory name one positional parameter or is the whole directory name one positional parameter?

Curiously, if I change "$@" to "$" the function works as well, so what's the difference as far as the program is concerned? I know that "$" is all the positional parameters, taken as one string.

I am not sure what you mean by "a directory with more than one word"? Can you provide an example?

I mean a directory with just that more than one word in its name -- say, for example my\ documents/ as opposed to just documents/

In this particular case, there is none ...

[house@leonov] more test.bash
#! /bin/bash
echo "\$@: '$@'"
echo "\$*: '$*'"
exit 0
[house@leonov] bash test.bash some folder
$@: 'some folder'
$*: 'some folder'

... but, of course, there are other cases :wink:

In this special case there is no effective difference between "$*" and "$@", because in bash the cd builtin accepts only one argument, the name of the directory you want to change to.

In ksh, cd takes optionally a second argument.

cd old new

where old ist substituted with new in the current directory name and then changed to this directory, like

$ pwd
/opt/software/app1/prod/install
$ cd app1 app2
/opt/software/app2/prod/install
$ pwd
/opt/software/app2/prod/install

In this special case it would make a difference, because "$@" would keep two arguments intact, even if they contain whitespace, whereas "$*" would combine arg1 and arg2 into one string.

It's not more than one word if you quote it. In that case, there is no field splitting done and it will always be one word (word in the bash man page sense) which happens to contain a space.

That is absolutely incorrect. If there are multiple arguments passed to a script or function, the double-quoted values "$*" and "$@" will ALWAYS differ. The former will always expand to one string, the latter to multiple strings.

If this function were called with two arguments, for example, it would try to cd into a directory named "$1" (as you pointed out, bash's built-in cd would ignore $2 and any other arguments). However, if the code were using "$*" instead, the bash builtin would be passed a single argument whose value would be "$1 $2". Definitely, not the same.

In this case, what is equivalent is the use "$@" and "$1", since bash's cd will ignore all other arguments.

Regards,
Alister

Alister.

I was not talking about scripts and functions in general, but this special case. And if this function is called properly, then there is only one argument.

Thats right, but this function does only have one argument. If more than one argument is passed, it is just a plain syntax error, which should be handled properly (which bash should do too - ignoring a syntax error doesn't seem to be a very good implementation).

When you call ksh's cd function with extra arguments (in this case a third one), it says

ksh: cd: bad argument count