当与 let 构造一起使用时,间距如何影响 globbing 运算符?

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

注意:一般建议使用(( ... ))而不是letlet 受分词和 glob 扩展的影响,这在算术评估中很少需要。来源:link link.

无论如何,我很想更好地理解 globbing 在以下 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

为什么 *let a=b*c 中未被评估为 globbing 运算符?


我使用了以下 bash 版本:

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

how globbing works

文件名扩展 替换 wordpattern 匹配的文件列表那种模式。您可以在 bash manual. See also man 7 glob.

中了解它

within the following bash let-constructs:

就像其他命令一样。 let 一点也不特别。

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

我不明白 a=b*c 是如何被名为 bcc 的文件替换的。 a= 怎么了? = 是一个普通字符。 a=b*cbcc 不匹配。例如,名为 a=bcc 的文件可以匹配 a=b*c.

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

是的,您只是没有匹配该 glob 的文件。

感谢@Renaud、@KamilCuk、@Ogus 和@user1934428 的评论和回答。你们热烈的讨论让我明白了我的思维错误是什么。

请允许我解释一下...我的不正确 的想法是通配符只发生在 = 字符.

不正确

所以我错误地认为发生了以下情况:

$ b=2
$ c=4

# 1. We first apply path expansion to `b*c` (INCORRECT)
# 2. I have the file 'bcc' in my current directory
# 3. So `b*c` expands to 'bcc' and we have `a=bcc`
# 4. I have no variable 'bcc' so 'a' should become 0
# 5. Then I got surprised because the result was 8 and 
#    after some probing, I posted this question on SE
$ let a=b*c
$ echo "${a}" 
8 

上面代码中的步骤'1.'是错误的,因为路径扩展恰好是a=b*c而不是b*c。而且,正如@KamilCuk 指出的那样:a=b*c 不匹配 bcc.

正确

所以会发生以下情况:

$ b=2
$ c=4

# 1. Path expansion is applied to `a=b*c` (CORRECT)
# 2. There is no match with `a=b*c` in the 
#    current directory so `a=b*c` is kept 
# 3. `a=b*c` undergoes arithmetic evaluation to a=8
$ let a=b*c
$ echo "${a}"
8

为了确认,我将名字奇怪的文件 a=b-matchglob-c 放在了我的目录中。
现在,有了这个文件在我的目录中,a=b*c 将扩展为 a=b-matchglob-c.

$ b=2
$ c=4

# 1. Path expansion turns a=b*c into 
#    let a=b-matchglob-c
# 2. Arithmetic evaluation will turn that into
#    let a=2-0-4
# 3. And 2-0-4=-2
$ let a=b*c
$ echo "${a}"
-2