DEV Community

Discussion on: Shellscripting: Functions

Collapse
ikirker profile image
Ian Kirker

One veeeery useful and slightly weird thing to add here is that $*, "$*", $@, and "$@" all mean "all the arguments", but get expanded in different ways.

Here's an example:

#!/bin/bash

function print_args() {
    echo "-- Unquoted, asterisk --"
    for i in $*; do
        echo $i
    done

    echo "-- Quoted, asterisk --"
    for i in "$*"; do
        echo $i
    done

    echo "-- Unquoted, atpersand --"
    for i in $@; do
        echo $i
    done

    echo "-- Quoted, atpersand --"
    for i in "$@"; do
        echo $i
    done
}

print_args "a" "b c" "d e f"
Enter fullscreen mode Exit fullscreen mode

gives:

-- Unquoted, asterisk --
a
b
c
d
e
f
-- Quoted, asterisk --
a b c d e f
-- Unquoted, atpersand --
a
b
c
d
e
f
-- Quoted, atpersand --
a
b c
d e f
Enter fullscreen mode Exit fullscreen mode

The quoted atpersand ("$@") option is the only option that preserves argument groupings including spaces, while "$*" treats all the arguments as one string, and $* and $@ both expand to the fully split, ungrouped, unquoted arguments.

"$@" behaves as if it were expanded with each element quoted separately, rather than "$*" which behaves as if it were expanded and then the whole expansion quoted.

(Note that this is the same as the behaviour for using arrays, in "${array[*]}" vs "${array[@]}".)

Collapse
puritanic profile image
Darkø Tasevski Author

I would agree on weird 😄but interesting nevertheless.
I didn't know about $* nor that quoting/unquoting can have such different results. Going to take note of this, thanks for sharing!