Getting all the arguments

We could adapt our preceding mkcd function to a new function, mkls, that creates directories and then prints them with ls -dl. The -d option to ls lists the directory itself, rather than its content. This implementation works well:

bash$ mkls() { mkdir -- "$1" && ls -dl -- "$1" ; }
bash$ mkls newdir
drwxr-xr-x 2 bashuser bashuser 4 2018-07-17 20:30:33 newdir/

However, this approach only allows us to create one directory. Because both mkdir and ls accept more than one directory name, we could create two of them like this:

bash$ mkls2() { mkdir -- "$1" "$2" && ls -dl -- "$1" "$2" ; }
bash$ mkls2 newdir1 newdir2
drwxr-xr-x 2 tom tom 4 2018-07-17 20:32:03 newdir1/
drwxr-xr-x 2 tom tom 4 2018-07-17 20:32:03 newdir2/

But that means the function no longer works correctly for only one directory, presenting an error:

bash$ mkls2 singledir
drwxr-xr-x 2 bashuser bashuser 4 2018-07-17 20:30:33 singledir/
mkdir: cannot create directory '': No such file or directory

It would be convenient to get all of the function's arguments within the function, no matter how many there were. Fortunately, Bash has a syntax for this, with the special "$@" expansion parameter:

bash$ mkls() { mkdir -- "$@" && ls -dl -- "$@" ; }
bash$ mkls dirset1 dirset2 dirset3
drwxr-xr-x 2 bashuser bashuser 4 2018-07-17 20:38:01 dirset1/
drwxr-xr-x 2 bashuser bashuser 4 2018-07-17 20:38:01 dirset2/
drwxr-xr-x 2 bashuser bashuser 4 2018-07-17 20:38:01 dirset3/

"$@" expands to all of the arguments given to the function, separately quoted. You can also check this for yourself by changing the shell's own positional parameters with calls to set and printf:

bash$ set -- arg1 'argument 2' '-third argument'
bash$ printf '%s\n' "$@"
arg1
argument 2
-third argument

The double quotes around $@ are just as important as they are around any other kind of variable or parameter expansion. Without them, special characters in the arguments might be interpreted by the shell, and may be broken up in a way you did not expect. You will never need an unquoted $@ for original, practical Bash scripts.