-2

From https://unix.stackexchange.com/a/94200/674

If there are no positional parameters ($# is 0), then "$@" expands to nothing (not an empty string, but a list with 0 elements)

So how differently do an empty string and a list with 0 elements behave?

Does "a list with 0 elements" mean "an array with 0 elements"? I don't see bash has the concept of list.

Can "nothing" mean something which is not necessarily a "list" or array?

dr_
  • 29,602
Tim
  • 101,790

2 Answers2

3

Yes, most shells do not have a concept of a list (for variables).
That is not a defined type of content (separate from string or number).

However, the parameters of a command are a list.

That is a very special kind of data type, one that only "$*" or "$@" would express as a list. But with differences:

$ set -- one two t33
$ printf '<%s> ' "$*" ; echo
<one two t33>

$ printf '<%s> ' "$@" ; echo
<one> <two> <t33>

$ for s; do printf '<%s>' "$s" ; done; echo
<one><two><t33>

Having explained that, what the quote means is that a list of parameters with 0 elements is equivalent to a list with no elements.

  • In short: the list disappears (there are no elements to print):

    $ set -- 
    $ echo $#
    0
    
    $ printf '<%s>' "$@" ; echo
    <>
    
    $ for s in "$*"; do echo "<a>" ; done
    <a>
    
    $ for s in "$@"; do echo "<a>" ; done
    $
    

The last code prints "nothing", not even an "empty" (null) string.

So, about your question:

Can "nothing" mean something which is not necessarily a "list" or array?

No, "nothing" is necessarily a (empty) "list". However, a "null string" is something.

1

Basically, $# gives you number of parameters. 0 is also a number, which indicates no parameters were gives. $@ however, expands to nothing, which means you can't evalute it. (e.g check if there were any parameters at all). Try it yourself in a script, and see how it behaves.

When you want to check how many parameters were provided, for example your script counts that 3 required parameters are provided - you would $#.

When you need to actually do something with the parameters, you would use $@.

See some examples from TLDP internal variables

Chen A.
  • 1,323