Search code examples
bashglobletarithmetic-expressions

How does spacing impact the globbing operator when used with a let construct?


Note: Generally it is advised to use (( ... )) over let. let is subject to word splitting and glob expansion, which is something you rarely want in arithmetic evaluation. Sources: link link.

Regardless, I would love to better understand how globbing works within the following bash let-constructs:

$ set -o xtrace  # used to figure out what is happening


# This section shows that globbing is performed
$ b=2
$ c=4

# watch out: '*' is the globbing operator here, so * expands 
# to the files in the current directory 
$ let a=b * c # This line will expand to: 
              #     let a=b bcc declaration.sh let-basics.sh c
              # Only 'b' will be evaluated because the remainder
              # after 'b' causes a syntax error.
$ echo "${a}" 
2             # Only b was evaluated so 2 is expected


# In contrast, it seems as if no globbing happens 
# here, even though there is a match on the 'bcc' file 
# in this directory.
$ let a=b*c
$ echo "${a}" 
8

Why isn't the * evaluated in let a=b*c as the globbing operator?


I used the following bash version:

$ bash --version
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)

Solution

  • how globbing works

    Filename expansion replaces a word that is a pattern by a list of files matching that pattern. You can learn about it in bash manual. See also man 7 glob.

    within the following bash let-constructs:

    Just like with any other commands. let is not special in any way.

    # here no globbing happens, even though there is a match on 
    # the 'bcc' file
    

    I do not see how a=b*c could be replaced by a file named bcc. What happened to a=? = is a normal character. a=b*c does not match bcc. For example, a file named a=bcc could match a=b*c.

    Why isn't the * evaluated in let a=b*c as the globbing operator?

    It is, you just have no files to match that glob.