"$@" will pass all arguments to
cd where as
$1 will only pass the first argument.
In your examples
$ . cdtest.sh "r st"
always works as you only pass in one argument, but if you were to pass in a flag as well such as
$ . cdtest.sh -L "r st"
"$@" will execute correctly where
"$1" will expand to
cd -L losing the directory entirely.
$ . cdtest.sh r st
Fails in both cases as you are passing two parameters to cd,
st which is not a valid way to execute cd. Parameters are separated by spaces which must be quoted (as in your first example) or escaped (
r\ st) to be treated as one argument.
In the case of cd however it is very uncommon to pass in flags and you cannot pass in multiple directories so you will not see the difference in a real world use of either
"$@" for cd. But for other commands you will notice a difference so it is best practice to always use
"$@" when you want to create a wrapper function or script like this.